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

先看代码:

class Base
{
    public:
        Base(int num):a(num) {std::cout << "Base() construct" << std::endl;}
        ~Base() {std::cout << "Base() deconstruct" << std::endl;}
        int Get() {return a;}
        
    private:
        int a;
};

void testc()
{
        std::cout << "******************************" << std::endl;
        std::cout << "******************************" << std::endl;
        
        Base *p;
        {
            std::weak_ptr<Base> gw;
            {
                auto sp = std::make_shared<Base>(42);
                gw = sp;
                p = sp.get();
            }
            std::cout << "shared_ptr release, p->a = " << p->Get() << std::endl;
        }
        std::cout << "weak_ptr release, p->a = " << p->Get() << std::endl;
}

void testd()
{
        std::cout << "==================================" << std::endl;

        
        Base *p;
        {
            std::weak_ptr<Base> gw;
            {
                std::shared_ptr<Base> sp(new Base(42));
                gw = sp;
                p = sp.get();
            }
            std::cout << "shared_ptr release, p->a = " << p->Get() << std::endl;
        }
        std::cout << "weak_ptr release, p->a = " << p->Get() << std::endl;
}

执行结果如下:

在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生命周期结束后,整块内存才一起被回收

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值