目录
3. operator new与operator delete函数
1. C/C++内存分布
程序编译好的二进制指令代码在程序运行时加载到代码段中,并在main函数开辟时,栈区和堆区数据会根据运行代码进行相对应空间开辟。
堆向上生长:先建立堆的地址小于后建立堆的地址
栈向下生长:先调用栈帧的地址比后调用的地址大
常量区被硬件保护,里面的内容不能被修改
练习题
2.new和delete操作符
针对内置类型new ~=malloc,delete~=free,只有用法区别
new 和 delete针对的更多是自定义类型
new的申请
- void testnew1()
- {
- int* p1 = new int;//后面的int是类型,申请一个int对象的堆空间
- int* p2 = new int[10];//开10个int大小堆空间
- int* p2p = new int[5]{ 1,2,3,4,5 }; //C98不支持对new数组初始化,C11支持,剩下没初始化值默认为0
- int* p3 = new int(5);//初始化一个int,值为5
-
- }
delete释放
注意事项:
1.匹配使用new和delete操作符;申请和释放连续的数组空间,使用 new[]和delete[]
- void testnew1()
- {
- int* p1 = new int;//后面的int是类型,申请一个int对象的堆空间
- int* p2 = new int[10];//开10个int大小堆空间
- int* p2p = new int[5]{ 1,2,3,4,5 };
- int* p3 = new int(5);//初始化一个int,值为5
-
- delete p1;
- delete[] p2;
- delete[] p2p;
- delete p3;
-
- }
3.new/delete 和 malloc/free最大区别是 new/delete对于【自定义类型】除了开空间 new会调用默认 构造函数,delete会调用析构函数,而malloc与 free不会。
new失败抛异常
malloc失败返回nullptr,new失败不需要检查返回值
- int main()
- {
- try
- {
- int* p1 = new int[1024*1024*10];
- }
- catch (const exception&e)
- {
- cout << e.what() << endl;
- }
-
- return 0;
- }
3. operator new与operator delete函数
new会开空间和调用构造函数,而在堆上开空间调用operator new,调用构造函数调用A::A
operator new不是对new运算符重载,operator new 和operator delete是系统提供的全局函数
operator new底层还是调用了malloc,只是对malloc封装+抛异常+调用构造函数处理
operator delete底层还是调用了free,加上了内存越界等机制
重载operator new与operator delete(不是运算符和函数重载)
不写默认调用库中函数,写了调用我们重载的函数
使用场景:
1.在使用new和delete申请和释放空间时,打印一些日志信息, 以简单帮助用户来检测是否存在内存泄漏
2.重载专属的operator new(例如内存池)
3.默认情况下使用全局库的operator new,但每个类可以有自己的operator new,就会调用自己写的
定位new
在已分配的原始内存空间中,显示调用构造函数初始化一个对象
使用格式:new (指针) type(参数)
- int main()
- {
- int* p1 = new int;
- new(p1)int(1);
- return 0;
- }
使用场景: 定位new表达式在实际中一般是配合内存池使用。因为内存池分配出的内存没有初始化,所以如果是自定义类型的对象,需要使用new的定义表达式进行显示调构造函数进行初始化即可使用