c++11 智能指针
c++中时常发生内存泄漏问题,在c++98中引入了auto_ptr指针,然而在c++11中已经摒弃了auto_ptr,新引入了三种智能指针模板(shared_ptr、unique_ptr、weak_ptr)。
首先我们需要了解内存是如何分配的?
void demo1()
{
int * pd = new int;
*pd = 10;
return;
}
demo1中,未使用任何智能指针。变量的分配步骤为三步,如此pd的内存并没有被释放。
- 为pd和一个int值分配存储空间
- 将值复制到动态内存中
- 删除pd,值保留在了动态内存中
void demo2()
{
auto_ptr<int> pd(new int);
*pd = 10;
return;
}
demo2中,内存的分配虽然也分为了三步,但是auto_ptr自带的析构函数会将内存释放。具体如下
- 为pd和一个int值分配存储空间
- 将值复制到动态内存中
- 删除pd,pd的析构函数释放动态内存。
那么既然已经有auto_ptr智能指针了,为什么还要引入新指针了,接下来的demo将会解开这个问题
void demo3()
{
auto_ptr<int> a(new int(5));
auto_ptr<int> b;
b = a;
cout << *a << endl;//Error:a已经将此块内存地址所有权转让给b
}
如果a和b是常规指针,那么两个指针指向同一块内存地址,在出作用域范围时,程序试图将内存释放两次,这样一来程序就会抛出异常。要避免这种问题,有以下几种解决方案
- 定义赋值运算符,执行深复制,使一个对象成为另一个对象的副本。存在于不同的内存空间中。
- 创建更高级指针,使用引用计数,计数为0时清空内存,避免同一内存块多次释放
auto_ptr 和 unique_ptr的区别
依旧是上面的demo3,使用auto_ptr 将会在程序运行时出错,而当使用unique_ptr时,程序在编译阶段直接报错!如果unique想使用所有权传递,那么使用std::move函数
void demo3()
{
unique_ptr<int> a(new int(5));
unique_ptr<int> b = a;//Error
unique_ptr<int> b = move(a);//Correct
cout << *b << endl;
}
Unique_ptr:release()函数,将原本绑定的独占式指针和对象进行分离,利用其它指针接收对象,独占式指针自动销毁
void demo4()
{
unique_ptr<int> a(new int(5));
int* c = a.release();
cout << *c << endl;
}
shared_ptr:引入了引用计数器,计数器归0,直接销毁对象
use_count计数,计算的是指向这个对象的个数,即指向该变量的地址,而不是这个指针被操作了多少次。
很显然,计数只针对于share_ptr,对于普通指针不进行计数