• std::make_shared和new初始化智能指针的区别


    先看代码:

    1. class Base
    2. {
    3. public:
    4. Base(int num):a(num) {std::cout << "Base() construct" << std::endl;}
    5. ~Base() {std::cout << "Base() deconstruct" << std::endl;}
    6. int Get() {return a;}
    7. private:
    8. int a;
    9. };
    10. void testc()
    11. {
    12. std::cout << "******************************" << std::endl;
    13. std::cout << "******************************" << std::endl;
    14. Base *p;
    15. {
    16. std::weak_ptr gw;
    17. {
    18. auto sp = std::make_shared(42);
    19. gw = sp;
    20. p = sp.get();
    21. }
    22. std::cout << "shared_ptr release, p->a = " << p->Get() << std::endl;
    23. }
    24. std::cout << "weak_ptr release, p->a = " << p->Get() << std::endl;
    25. }
    26. void testd()
    27. {
    28. std::cout << "==================================" << std::endl;
    29. Base *p;
    30. {
    31. std::weak_ptr gw;
    32. {
    33. std::shared_ptr sp(new Base(42));
    34. gw = sp;
    35. p = sp.get();
    36. }
    37. std::cout << "shared_ptr release, p->a = " << p->Get() << std::endl;
    38. }
    39. std::cout << "weak_ptr release, p->a = " << p->Get() << std::endl;
    40. }

    执行结果如下:

    在testc()中,只有weak_ptr生命周期也结束后,Base对象内存才真正被回收,虽然Base在shared_ptr生命周期结束后就执行了析构函数,但对象所占用的内存还未被马上回收。

    而在testd()中,由于使用了new分配对象内存,Base对象内存和智能指针控制块内存不在一起,所以当shared_ptr生命周期结束后就释放了Base对象所占内存。

    结论:

    1、make_shared只分配一次内存,智能指针控制块和管理的对象存在同一块内存里。new初始化智能指针需要调用两次内存分配,一次给控制块分配内存,一次给对象分配内存。

    2、异常安全性。当在函数的实参里初始化智能指针,使用new初始化有发生异常安全性的风险,如 function_a(std::shared_ptr ptr1(new int(100)), function_b()); 编译器可能产生代码: 1先new对象,2再执行函数function_b,3最后将new对象的指针赋给智能指针,如果第2步 function_b发生异常退出,将导致内存泄漏。

    3、对象内存被延迟回收:当使用了弱指针weak_ptr引用shared_ptr时,使用make_shared初始化因为控制块和对象都在同一块内存里,虽然管理的对象已经执行析构函数,但由于weak_ptr没有释放,导致内存生命周期被意外延长,只有weak_ptr生命周期结束后,整块内存才一起被回收

  • 相关阅读:
    HarmonyOS应用开发者考试认证含初,高级题库
    20 分钟搭建一个串流服务器
    嵌入式学习笔记(41)SD卡启动详解
    浅谈Python中列表元素的修改以及列表的统计与排序
    温故而知新九(C++)
    系统设计综述——个人思考总结
    在做事上面体现出来,您之心胸所在,心有惊雷而面不改色,可拜上将军---程序员
    go slice 扩容机制
    VS_QT_4_Qt设计师
    故障诊断模型 | Maltab实现SVM支持向量机的故障诊断
  • 原文地址:https://blog.csdn.net/xieshangjian/article/details/132714517