一、内存分配规则
栈 | 在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。 |
堆 | 这部分内存由new/malloc来分配,在程序运行时编译器不会主动去释放,需要通过delete/free手动释放,而程序结束会回收内存。 |
自由存储区 | 该区域是C++基于new抽象的一个概念,通过new操作符进行内存申请的内存就称作自由存储区。而自由存储区不仅可以是堆,还可以是静态存储区,关键在于operator new的具体实现方式。(operator new + 构造函数 是new的构成) |
静态存储区 | 用于存储静态变量和全局变量 |
常量存储区 | 用于存储常量,不允许被修改 |
二、new与delete
new操作符用于为非内置类型申请内存,其底层实现是借助malloc函数。(new[]用于申请多份内存实现数组)
同理,new[] 就是先执行 operator new[] 再执行n次构造
delete操作符用于回收new申请的内存。(delete[]释放new[]申请的内存)
先析构再回收内存是为了防止对象的成员有申请的内存没有回收造成内存泄漏
使用方法
new和new[]的区别
与new不同的是,new[] 申请内存时会多分配 sizeof(size_t) 的内存大小来记录数组的元素个数,这样 delete[] 才能准确知道调用多少次析构函数。
如果用 delete 来释放 new[] 申请的内存会出错。
三、new/delete与malloc/free的区别
注:new/delete与malloc/free在内置类型上区别不大,主要在用法上略有不同。
- new的返回类型是相应类型的指针;malloc返回的是 void* 的指针,需要强制类型转换。
- new可以为非内置类型分配内存,且会自动调用相应的构造函数;malloc无法为非内置类型分配内存,且无法调用构造函数。
- delete会调用析构函数;free则不会调用析构函数
- new申请内存失败会抛出bac_alloc异常;而malloc会返回NULL。(如下)
int main()
{
try
{
int* p = new int[10000000000];
}
catch (bad_alloc& memExp)
{
//终止程序,或者重分配,又或者给出异常
cerr << memExp.what() << endl;
//cerr 标准错误输出流
}
return 0;
}