根据用于分配内存的方法,c++有3种内存管理方式:自动存储,静态存储和动态存储
其中静态存储用于存储一些整个应用程序执行期间都存在的静态变量,动态存储用于存储上一节讲述的通过new分配的内存单元。
而对于在函数内部定义的常规变量则使用自动存储空间,其对应的变量称为自动变量。自动变量在所属的函数被调用时自动产生,在该函数结束时消亡。实际上,自动变量是一个局部变量,其作用域为包含它的代码块。自动变量通常存储在栈上,这意味着进入代码块时,其中的变量将依次加入到栈中,而在离开该代码块时按相反的顺序释放这些变量。
由于自动变量通常不会导致内存问题,所以智能指针试图通过将一个动态分配的内存单元与一个自动变量关联,这个自动变量在离开代码块被自动释放的时候释放其内存单元,这使得程序员不再需要显式地调用delete就可以很好的管理动态分配的内存。
c++11使用三种不同的智能指针,unique_ptr,shared_ptr 和weak_ptr.他们都是模板类型。我们可以通过如下的方式来使用他们
int main(){
unique_ptr up1(new int(11));
unique_ptr up11 = up1;//编译报错
shared_ptr up2(new int(22));
weak_ptr up3 = ip2;
}
每个智能指针都重载了*运算符,我们可以使用*up1这样的方式来访问所分配的堆内存。。。。
智能指针在析够或者调用reset成员的时候,都可能释放其所拥有的堆内存。三者之间的区别如下:
unique_ptr不能与其他智能指针共享所指对象的内存,例如通过将up1赋值给up11将会导致编译错误。但可以通过标准库的move函数来转移unique_ptr对对象的”拥有权”,一旦转移成功,原来的unique_ptr指针就失去了对象内存的所有权,再使用则会导致运行时错误。
多个shared_ptr则可以共享同一堆分配对象的内存,它在实现上采用引用计数,一旦一个shared_ptr放弃了所有权(调用了reset成员)并不会影响其他智能指针对象。只有所有引用计数归零的时候,才会真正释放所占有的堆内存的空间。
weak_ptr可以用来指向shared_ptr分配的对象内存,但是却并不拥有该内存,我们可以使用其lock成员来访问其指向内存的一个shared_ptr对象,当其所指向的内存无效时,返回指针空值(nullptr)。weak_ptr通常可以用来验证shared_ptr的有效性。