1. 内存分布
内存区域的划分:
- 栈——存放局部变量,函数返回值等,是向下扩展的。
- 堆——动态内存分配的区域,是向上扩展的。
- 数据段——全部变量和静态变量存放的位置。
- 代码段——可执行代码和可读常量的存放的位置。
2. C语言和C++动态内存开辟的区别
- c使用的是函数(malloc,calloc,realloc和free),而在c++中引入了new和delete两个关键字
- c++除了用法方便和c语言没有什么本质的区别
- 对于自定义类型,C语言只是开辟空间和释放空间,但是new/dele关键字,在开辟的空间之后是会调用自定义类型的构造函数,释放空间时会调用自定义类型的析构函数
- C++中是没有C语言中realloc函数扩展空间的功能,是需要自己手动实现的
- 在C++中new申请是否失败是不需要我们手动判断的,new的底层抛异常已经帮我们实现了
//用例显示
int *p1=new int(10); //申请一个int类型的空间,并初始化为10
int *p2=new int[10]{1,2,3,4,5}
//申请10个int类型的空间,并初始前面五个int空间,实际上是申请了44个空间,前面4个空间来放申请对象的数量,这多开的4个空间取决于是否需要有显示的析构函数
//释放空间
delete p1; //只申请一个空间的释放方法
delete[] p2; //申请多个空间的释放方法
申请销毁单个空间的格式:
int *p1=new int(10);
关键字new+需要申请的类型+对应类型的初始化
delete p1;
关键字delete+只想申请空间的指针
申请销毁对个空间的格式
int *p2=new int[10]{1,2,3,4,5}
关键字new+需要申请的类型+[需要申请的类型的个数]+{对应类型的初始化}
delete[] p2;
关键字delete+[]+指向申请空间首个类型的指针
3. operator new与operator delete函数
new和delete是用户进行动态内存申请和释放的操作符,operator new 和operator delete是
系统提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过
operator delete全局函数来释放空间。
operator new与operator delete函数
- 上面讲了new/dele关键字,new在底层调用operator new全局函数来申请空间,delete在底层通过operator delete全局函数来释放空间。
- 实际上,operator new与operator delete函数的申请和销毁空间的操作也是由malloc和free函数实现的,只是添加了一些其他功能(抛异常)进行了封装。
- new=operator new(malloc+抛异常)+构造函数;delete=析构函数+operator delete(free)
4. new和delete的实现原理
4.1 内置类型
- new/delete和malloc/free的使用相同,并没有什么区别
- new/delete是申请和释放单个空间, new[]/delete[]是申请和释放多个空间
4.2 自定义类型
- new的实现
- 使用operator new函数开辟空间
- 调用自定义类型的构造函数
- delete的实现
- 调用自定义类型的析构函数
- 使用operator delete函数销毁空间
- new[n]的实现
- 使用operator new函数开辟连续空间
- 调用自定义类型的构造函数对前n个对象进行初始化
- delete[]的实现
- 调用自定义类型的析构函数对前n个对象进行析构,进行资源清理
- 使用operator delete函数销毁连续空间
注意:
上面也可以看出new/delete关键字的功能是比malloc/free函数的多,因此在使用的时候,尽量对应使用new对应使用delete,malloc对用使用free,不要进行错误的对应使用,这样会很容易出现问题。