【C++11】shared_ptr

C++内存管理

C++11提供了3种智能指针:shared_ptr,unique_ptr, weak_ptr引用自头文件memory。

基本用法可以直接查找文档,这里有些需要注意的地方。

不要用一个原始指针初始化多个shared_ptr

        int* ptr = new int();
        std::shared_ptr<int> p1(ptr);
        std::shared_ptr<int> p2(ptr);

不要再函数实参中创建shared_ptr

function(shared_ptr<int>(new int), g());

不同的编译器的参数计算顺序是不同的,一般是右往左,但是也可能是先new int,然后调用g(),如果g()发生异常,则shared_ptr还没有被创建,int被内存泄漏。正确如下:

shared_ptr<int> ptr(new int)
function(ptr, g());

返回this指针需要注意的地方

struct A
{
    std::shared_ptr<A> getSelf()
    {
        return std::shared_ptr<A>(this);
    }

    ~A()
    {
        cout << "delete self" << this << endl;
    }
};


int main()
{
    {
        std::shared_ptr<A> sptr1(new A);
        std::shared_ptr<A> sptr2 = sptr1->getSelf();
    }
    return 0;
}

这里析构函数会被调用2次,同一个指针构造了2个智能指针,他们之间没有任何关联,所以正常释放时,内存会被释放两次。

正确的做法是如下:派生自std::enable_shared_from_this类

struct A : public std::enable_shared_from_this<A>
{
    std::shared_ptr<A> getSelf()
    {
        return shared_from_this();
    }

    ~A()
    {
        cout << "delete self:" << this << endl;
    }
};

但是该类的构造必须是智能指针(shared_ptr)。如果是一个普通指针则会抛出一个:std::bad_weak_ptr异常。

避免循环引用

可能会导致内存泄漏

struct B;
struct C;

struct B
{
    std::shared_ptr<C> cptr;
    ~B()
    {
        cout << "delete B" << endl;
    }
};

struct C
{
    std::shared_ptr<B> bptr;
    ~C()
    {
        cout << "delete C" << endl;
    }
};
        //使用如下
        std::shared_ptr<B> bptr(new B);
        std::shared_ptr<C> cptr(new C);

        bptr->cptr = cptr;
        cptr->bptr = bptr;

这样会导致B和C都不会被释放,存在内存泄漏问题。解决办法就是可以将其中一个shared_ptr修改为weak_ptr。

猜你喜欢

转载自blog.csdn.net/gx864102252/article/details/79980832