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。