目录:
一:C和C++内存分布
二:C动态内存管理方式
三:C++动态内存管理方式
四:operator new与operator delete函数
五:new和delete的实现原理
六:定位new表达式(placement-new)
七:经典面试题
思维导图:
1:C和C++内存分布
接下来我们来做个题:
以下变量存放在哪一个区域:
问题1:
globalVar在哪里?____ staticGlobalVar在哪里?____
staticVar在哪里?____ localVar在哪里?____
num1 在哪里?____
问题2:
注解:
1.) 栈又叫堆栈--非静态局部变量/函数参数/返回值等等,栈是向下增长的。
2. )内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口
创建共享共享内存,做进程间通信。(Linux课程如果没学到这块,现在只需要了解一下)
3. )堆用于程序运行时动态内存分配,堆是可以上增长的。
4.) 数据段(也被称为数据区、静态数据区、静态区)--存储全局数据和静态数据。
5.) 代码段(常量区)--可执行的代码/只读常量
2:C动态内存管理方式
void Test ()
{
int* p1 = (int*) malloc(sizeof(int));
free(p1);
int* p2 = (int*)calloc(4, sizeof (int));
int* p3 = (int*)realloc(p2, sizeof(int)*10);
free(p3 );
}
2.1 malloc,realloc,calloc 区别
malloc:在堆上开辟一块空间
realloc:进行对空间的扩容,可能原地扩,也可能异地扩
calloc:开辟空间并把开好 的空间进行初始化
2.2 动态开辟的内存需要frre?
毋庸置疑的,必须进行释放,否则会造成内存泄漏
3:C++动态内存管理方式
通过new和delete操作符进行动态内存管理。
3.1 对内置类型的处理
//注意:申请和释放单个元素的空间,使用new和delete操作符后面加变量名字,
// 申请和释放连续的空间,使用new[]和delete[]在加名字,
//注意:匹配起来使用。
3.2对自定义类型的处理
对于自定义类型的delete 和内置类型的销毁是不一样的在底层逻辑上:
注意:在申请自定义类型的空间时,new会调用构造函数,delete会调用析构函数,而malloc与free不会。
4:operator new与operator delete函数
new和delete是用户进行动态内存申请和释放的操作符,operator new 和operator delete是
系统提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过operator delete全局函数来释放空间。operator new 实际也是通过malloc来申请空间,如果malloc申请空间成功就直接返回,否则执行用户提供的空间不足应对措施,如果用户提供该措施就继续申请,否则就抛异常。operator delete 最终是通过free来释放空间的。
5:new和delete的实现原理
new , delete 对自定义类型的处理机制
new 的原理1. 调用 operator new 函数申请空间2. 在申请的空间上执行构造函数,完成对象的构造delete 的原理1. 在空间上执行析构函数,完成对象中资源的清理工作2. 调用 operator delete 函数释放对象的空间new T[N] 的原理1. 调用 operator new[] 函数,在 operator new[] 中实际调用 operator new 函数完成 N个对象空间的申请2. 在申请的空间上执行 N次构造函数delete[ ] 的原理1. 在释放的对象空间上执行 N 次析构函数,完成 N 个对象中资源的清理2. 调用 operator delete[] 释放空间,实际在 operator delete[] 中调用 operator delete 来释放空间
6:定位new表达式(placement-new)
定位 new 表达式是在 已分配的原始内存空间中调用构造函数初始化一个对象 。使用格式:new (place_address) type 或者 new (place_address) type(initializer-list)place_address 必须是一个指针, initializer-list 是类型的初始化列表使用场景:定位 new 表达式在实际中一般是 配合内存池使用 。因为内存池分配出的内存没有初始化,所以如 果是自定义类型的对象,需要使用new 的定义表达式进行显示调构造函数进行初始化。
7:经典面试题
7.1malloc,free 和new , delete区别
malloc/free 和 new/delete 的共同点是:都是从堆上申请空间,并且需要用户 手动释放 。不同的地 方是 :1. malloc 和 free 是 函数 , new 和 delete 是 操作符2. 初始化问题: malloc 申请的空间不会初始化, new 可以初始化3. malloc 申请空间时,需要手动计算空间大小并传递, new 只需在其后跟上空间的类型即可如果是多个对象,[ ] 中指定对象个数即可4. 是否强转 : malloc 的返回值为 void*, 在使用时必须强转, new 不需要,因为 new 后跟的是空间的类型5. 是否判空 : malloc 申请空间失败时,返回的是 NULL ,因此使用时必须判空, new 不需要,但是 new 需 要捕获异常6. 是否额外调用函数 : 申请自定义类型对象时, malloc/free 只会开辟空间,不会调用构造函数与析构函数,而 new 在申请空间后会调用构造函数完成对象的初始化,delete 在释放空间前会调用析构函数完成 空间中资源的清理
7.2内存泄漏定义以及危害
什么是内存泄漏:内存泄漏指因为疏忽或错误造成程序 未能释放已经不再使用的内存 的情况。内 存泄漏并不是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对 该段内存的控制,因而造成了内存的浪费内存泄漏的危害:长期运行的程序出现内存泄漏,影响很大,如操作系统、后台服务等等,出现 内存泄漏会导致 响应越来越慢,最终卡死。