动态内存与智能指针

C++中动态内存的分配是在堆中进行的,主要通过下面3个方面:

1.new和delete

new和delete很常见,new运算符分配内存,并且同时调用对象的构造函数,delete释放内存,并且调用对象的析构函数,但是new 和delete管理内存需要手动分配和释放内存,然而在程序中很难选择适当的时机释放内存,所以C++又引入了智能指针。

delete释放内存时候需要注意的问题:

(1)必须释放由new运算符分配的内存

(2)同一块内存不可以释放多次

(3)可以释放指向nullptr的指针

(4)释放内存结束后应该将指向该内存的指针置为nullptr

2.智能指针

智能指针和常规指针的重要区别就是它可以自动释放所指向的对象,常见智能指针有如下3种:

(1)shared_ptr

它允许多个指针指向同一个对象,他有一个计数器,用来保存该对象的指针数,当拷贝一个shared_ptr指针时,该指针的计数器+1,当一个我们给shared_ptr赋一个新值或者shared_ptr被销毁时候,计数器-1,只有当计数器为0的时候,才会释放该shared_ptr指向的内存。

shared_ptr独有的操作:

make_shared<T>(args)    返回一个shared_ptr,指向类型T的对象,args为初始化参数(自动调用该对象的构造函数来初始化)

例:shared_ptr<int> ptr=make_shared<int>(10)     //指向一个初始值为10的int的shared_ptr

shared_ptr<T> p(ptr)   p是ptr指针的一个拷贝,ptr的计数器+1   注:下面的unique_ptr指针不能拷贝初始化,因为unique_ptr只能有一个指针占有

p=q   p和q所保存的指针必须能相互转化,p的计数器-1,q的计数器+1

p.use_count()    表示p共享对象的智能指针数量

p.unique()      表示p共享对象的智能指针数量是否为1,是则返回true,否则返回false

(2)unique_ptr

只能有一个指针指向对象,当unique_ptr被销毁时,它所指向的对象也被销毁

它的初始化一般结合new进行:

例:unique_ptr<string> p(new string("hello"));

unique_ptr常用操作:

u.release()   放弃u对对象的控制权,返回指针,u为nullptr

u.reset()     释放u所指向的对象

u.reset(p)   将u指向内置指针p所指向的对象

初始化的时候虽然不能使用拷贝或赋值,但可以使用release或者reset将指针的所有权从一个unique转移到另一个unique

例如:unique_ptr<string> p1(p2.release());   //p2被初始化为p1原来保存的指针,p1置为空

p2.reset(p1.release())    //将p1的所有权转交给p2,p1置为空

(3)weak_ptr

它指向一个shared_ptr指针所指向的对象,但是不会改变shared_ptr计数器,同样,shared_ptr计数器为0的时候,即使有weak_ptr指向对象,该对象还是会被释放,这就是弱共享对象的特点,它同样使用make_shared<T>来初始化

3.allocator

特点:new将内存分配和对象构造组合到了一起,而allocator将他们分离开了

用allocator分配内存主要经历下面几个步骤:

(1)声明allocator对象

allocator<int>  all;//可以分配int的对象

(2)分配空间(未构造)

auto const p=all.allocate(n)//分配n个未初始化的int

(3)构造对象

all.construct(p,4);//构造一个值为4的对象

(4)销毁对象

all.destory(--p);//调用对象的拷贝构造函数,该对象必须已经构造

(5)释放内存

all.deallocate(p,n);//必须在destory之后,p必须是allocate返回的指针,n必须为p创建时要求的大小

posted @ 2015-08-26 21:12  runninglzw  阅读(186)  评论(0编辑  收藏  举报