内存分类:
(1)静态内存:静态内存中的对象的生命周期和程序的生命周期一样长。
(2)栈内存:栈内存中的对象的声明周期较短,和局部函数的生命周期一样长。
(3)堆内存:又称自由空间,是程序的内存池。堆内存用来存储动态分配对象,即那些在程序运行时分配的对象。对象的生命周期从从分配开始直到显式销毁一直存在。
三者的区别与联系:
分配在静态或栈中的对象由编译器自动创建和销毁。但在创建时,栈对象仅在定义时才存在,static对象在使用之前分配,在程序结束时销毁。
智能指针:shared-ptr,unique-ptr,weak-ptr,都是模板类。
shared-ptr<string> p;
shared-ptr<int> p3=make-shared-ptr<int>(42);
shared-ptr自动销毁所管理的对象(有条件):通过模板类的析构函数,调用所销毁对象的析构函数。
======================================================================
new
在自由空间分配的内存是无名的,因此new无法为其分配的对象命名,而是返回一个指向该对象的一个指针。
string *p=new string(10,‘9’);
比较下面两个new的不同:
int *pit1=new int;//默认初始化,*pit1的值未定义
int *pit2=new int();//值初始化,*pit2=0;
由于编译器要使用初始化器的类型来推断要分配的类型,只有当括号中仅有单一的初始化器的时候才可以使用auto:例
auto p1=new auto(obj);//正确
auto p2=new auto(a,b,c);//错误
delete
delete发生时的动作:(1)销毁给定指针指向的对象(2)释放内存(可以理解为格式化物理内存)。注意,此时指针本事并没有销毁,此时的指针仍然保存着对象的地址,虽然对象已经不存在。
shared_ptr 与new
shared_ptr<int>p2(new int (42));//正确
shared_ptr<int>p1=new int(42);//错误,原因接受指针参数的智能指针的构造函数是explicit的,即禁止内置指针向智能指针的隐式转换。
shared_ptr<int> p(new int(42));
p.get();//由智能指针返回内置指针。
数组与动态分配
(1)delete[];
(2)智能指针与动态数组
unique_ptr<int []> up(new int [10]);
up.release;//自动调用delete[]
与unique_ptr不同,shared_ptr不直接支持管理动态数组。如果希望使用shared_ptr管理一个动态数组,必须提供自己的删除器:
shared_ptr<int>sp(new int[10],[](int *p) {delete [] p ; });
sp.rest();//使用我们提供的lambda释放数组,此使用delete[]
================================================================================================
allocator类
模板,将内存分配和对象构造分离;
用法:
allocator<string> allo;//声明对象可分配string
auto cons p=allo.allocate(n);//分配n个未初始化的string
allo.construct(q++,10,’c’);//为分配的内存构造对象
allo.destroy(q);//析构对象
allo。deallocate(p,n);//释放内存(格式化物理内存)
拷贝和填充未初始化的内存:
uninitialized_copy(b,e,b2);
uninitialized_copy_n(b,n,b2);
uninitialized_file(b,e,t);
uninitialized_copy_n(b,n,t)