关于new delete,重载new delete (new express、operator new、array new、placement new)

讲自由存储区和堆的关系:https://www.cnblogs.com/qg-whz/p/5060894.html

视频链接: https://www.bilibili.com/video/av19038490/?p=8

1. new和delete对象时 编译器的执行过程(new表达式)

在我们 new 一个对象时,编译器大致分三个步骤进行:

  1. 分配对象尺寸大小的空间
  2. 将void指针转型为complex指针
  3. 通过2这根指针去调用构造函数

delete 这个对象指针时,编译器分为两个步骤:

  1. 调用析构函数
  2. 释放内存
    在这里插入图片描述
    在这里插入图片描述

2. 动态分配所得内存的情况

2.1 new对象时

debug模式下系统为 一个对象分配的内存情况 是带第一块和第三块。
上和底部红色为cookie(用于记录整块内存大小,方便回收),青色为complex数据大小8字节,灰色为调试模式下编译器多加的部分,最终内存大小必须是16的倍数,绿色为其填补。
release 模式下没有灰色部分,内存大小为16,程序员能看到的只是数据的大小8字节,不包含上下coolie大小。最终内存大小也必须是16的倍数。

cookie作用:用于记录整块内存大小,方便回收。其内容记录为size+1(size为此对象所占内存的大小,1表示是分配或回收的状态,16位整数倍所以最后4位都可以用)。
在这里插入图片描述

2.2 new数组时 (array new)

new array[3] 内存里会多4个字节用于计数 (counter)数组的长度。
new array[3] 一定要和 delete[] 搭配,否则内存泄漏。delete告诉编译器删除一个指针,delete[]告诉编译器删除一个数组。
在这里插入图片描述

3. 重载 operator new; operator delete; operator new; operator new[]; (operator new)

可以用在内存管理,内存池设计。
new complex; 这里的new是expression表达式,分解的三个步骤这个事实不能改变,但是步骤里调用的operator new可以重载。delete一样。
在这里插入图片描述
在这里插入图片描述

3.1 重载全局的operator new/delete/[]

重载的是全局的new,只有编译器会去调用它们,可能导致系统崩掉。
在这里插入图片描述

3.2 重载member new/delete

在这里插入图片描述
在这里插入图片描述

3.3 示例(operator new)

如果程序员这么写 Foo* pf = ::new Foo; ::delete pf; 就是会绕过重载的那个new/delete,直接使用全局的new/delete。
在这里插入图片描述
在这里插入图片描述

4. 重载operator new()、operator delete() (placement new())

4.1 operator new()

我们可以重载class member operator new(),写出多个版本,前提是每一版本的声明都必须有独特的参数列,其中第一个参数必须是size_t,其余参数以new所指定的placement argument为初值,出现于new(…)小括号内的便是所谓placement arguments
在这里插入图片描述
如下在构造函数中故意抛出异常。
在这里插入图片描述
第五个重载函数operator new()的第一个参数为long型,编译报错。
在这里插入图片描述

4.2 operator delete()

我们也可以重载class member operator delete(),写出多个版本。但他们绝对不会被 delete 调用。只有当 new 所调用的ctor抛出exception,才会调用这些重载版本的operator delete()。它只可能这样被调用,主要用来归还未能完成创建成功的object所占用的memory。

构造一个对象时:在调用其中一个operator new()分配完空间后, 调用构造函数时出现异常,在构造这个对象过程中出错,但是此时空间已经分配出来了,所以释放掉这个内存,否则内存泄漏。(operator delete()是,在构造对象出错后,给一个机会去释放内存

如下在构造函数中故意抛出异常。
在这里插入图片描述
如下构造p5这个对象时不会调用默认构造,会调用自己写的那个 专门抛出异常的构造函数。然后编译器调用对应operator delete()但是如果没有写operator delete()编译器也不会去care,毕竟new的内存回收由程序员决定。
在这里插入图片描述

4.3 示例(placement new)

标准库的例子string,其中Rep用作reference counter。
在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值