1. 内存分布
- 静态内存:局部static对象、类static数据成员、定义在任何函数之外的变量;使用之前分配内存,程序结束时销毁;
- 栈内存:函数内的非static对象;仅在程序块运行时才存在;
- 堆:存储动态分配对象;
2. 直接管理内存
new动态分配内存、初始化
-
使用new动态分配内存返回一个内置指针,使用 new 在堆上创建出来的对象是匿名的,没法直接使用,必须要用一个指针指向它,再借助指针来访问它的成员变量或成员函数
-
动态分配的对象是默认初始化的,即内置类型不初始化(未定义的),类类型执行默认构造函数;
string *ps=new string;//ps指向一个动态分配的,初始化为空string的对象
int *pi=new int;//pi指向一个动态分配,未初始化的int对象
- 直接初始化:
int *pi=new int(1024);
string *ps=new string(10,'9');
vector<int> *pv=new vector<int>{0,1,2,3,4,5,6};
- 值初始化:
int *pi=new int(); //值初始化为0
string *ps=new string();//值初始化为空string
内存耗尽
- 对于
int *pi=new int;
,如果分配失败,new抛出std::bad_alloc
- 对于
int *p = new (nothrow) int;
,如果分配失败,p指针为空指针:
delete释放动态内存
delete p;
p必须是一个指向动态分配对象的指针或者是一个空指针, 不能使用 delete 删除在栈上创建的对象;- delete执行的两个动作:销毁指针指向的对象,释放对应的内存;
- 未定义的行为:释放一个非new生成的指针,或者相同的指针释放多次;
- 由内置指针管理的动态内存在被显式释放前会一直存在;
- 指针被delete之后,就变成了空悬指针,为了安全,最好将空悬指针置为空指针nullptr;
share_ptr和new结合使用:
- 智能指针类定义中,接受内置指针参数的构造函数是explicit的,即不存在内置指针到智能指针的隐式转换,因此智能指针初始化的时候必须直接初始化,不能拷贝初始化:
shared_ptr<int> p1 = new int(1024);//错误,内置指针不能隐式转换为智能指针
shared_ptr<int> p2(new int(1024));//正确,直接初始化
new动态数组
- 返回指向第一个对象的指针:
int *p=new int[42];
delete释放动态数组
delete [] p;