先写一个demo,里面有new[],delete[],使用C++11 MTd选项编译:


#include <string>
int main()
{auto pS = new std::string[10];delete[] pS;return 0;
}

new的大小为0x11c,十进制284,相当与10*28 + 4。4个额外申请的长度就是保存数组大小用的。

auto pS = new std::string[10];
009C970D  push        11Ch
009C9712  call        operator new[] (09C376Ch)
009C9717  add         esp,4
009C971A  mov         dword ptr [ebp-0F8h],eax

在new返回的地址先写入的数组的长度10,注意返回给用户的地址是这个地址+4后的长度。

009C972E  je          main+9Ah (09C976Ah)
009C9730  mov         eax,dword ptr [ebp-0F8h]
009C9736  mov         dword ptr [eax],0Ah

数组对象开始调用构造函数初始化:

009C973C  push        9C3FB9h
009C9741  push        9C31DBh
009C9746  push        0Ah  //对象的个数
009C9748  push        1Ch  //对象的大小
009C974A  mov         ecx,dword ptr [ebp-0F8h]
009C9750  add         ecx,4
009C9753  push        ecx  //将new返回的地址+4就是第一个对象的首地址
009C9754  call        `eh vector constructor iterator' (09C3EECh)
009C9759  mov         edx,dword ptr [ebp-0F8h]
009C975F  add         edx,4
009C9762  mov         dword ptr [ebp-10Ch],edx//注意这里返回的地址是+4的,这是用户拿到的地址。复制流是这样的[ebp-10ch]->[ebp-104h]->ecx->pS
009C9768  jmp         main+0A4h (09C9774h)
009C976A  mov         dword ptr [ebp-10Ch],0
009C9774  mov         eax,dword ptr [ebp-10Ch]
009C977A  mov         dword ptr [ebp-104h],eax
009C9780  mov         dword ptr [ebp-4],0FFFFFFFFh
009C9787  mov         ecx,dword ptr [ebp-104h]
009C978D  mov         dword ptr [pS],ecx

所以我们调用new[]多个对象的时候,返回地址-4上保存着这个对象数组的大小。
接着我们看delete[]的时候是怎么用的:上来就是空指针检查,即使我们C++代码里面没有写。

delete[] pS;
009C9790  mov         eax,dword ptr [pS]
009C9793  mov         dword ptr [ebp-0E0h],eax
009C9799  mov         ecx,dword ptr [ebp-0E0h]
009C979F  mov         dword ptr [ebp-0ECh],ecx
009C97A5  cmp         dword ptr [ebp-0ECh],0  //检查pS是否为NULL
009C97AC  je          main+0F3h (09C97C3h)
009C97AE  push        3
delete[] pS;
009C97B0  mov         ecx,dword ptr [ebp-0ECh]
009C97B6  call        std::basic_string<char,std::char_traits<char>,std::allocator<char> >::`vector deleting destructor' (09C4216h)

跟入vector deleting destructor函数看看:先[pS-4]取数组的的长度,调用析构函数,然后delete释放内存。

009C78DB  push        9C3FB9h
009C78E0  mov         eax,dword ptr [this]  //取pS的值
009C78E3  mov         ecx,dword ptr [eax-4]  //取对象数组的长度
009C78E6  push        ecx  //string对象的个数10
009C78E7  push        1Ch  //strig对象的大小
009C78E9  mov         edx,dword ptr [this]
009C78EC  push        edx
009C78ED  call        `eh vector destructor iterator//调用string析构函数
009C78F2  mov         eax,dword ptr [ebp+8]
009C78F5  and         eax,1
009C78F8  je          std::basic_string<char,std::char_traits<char>,std::allocator<char> >::`vector deleting destructor'+59h (09C7909h)
009C78FA  mov         eax,dword ptr [this]
009C78FD  sub         eax,4  //pS-4才是申请堆block的首地址,然后delete释放。
009C7900  push        eax
009C7901  call        operator delete[] (09C3136h)
009C7906  add         esp,4

总结:delete[]参数不用输入数组的长度,是CRT实现new的时候在堆userdata首地址放上了数组长度,new返回的地址是申请到地址+4的值。然后delete[]释放的时候,用传入地址-4拿数组长度,实现数组释放。

c++ new[] delete[]底层分析相关推荐

  1. new和delete底层解析

    new和delete底层解析 2018年04月05日 10:26:44 龙跃十二 阅读数:205 标签: C++newdelete 更多 个人分类: C++ 所属专栏: C++ 版权声明:本文为博主原 ...

  2. Android底层隐私数据,Android Intent传递数据底层分析详细介绍_Android_脚本之家

    Android  Intent传递数据底层分析详细介绍 我们知道在Activity切换时,如果需要向下一个ActivityB传递数据,可以借助Intent对象的putExtra方法. 但是不知各位有没 ...

  3. 【Python基础避坑】函数内存底层分析,全局变量/局部变量,参数传递,浅拷贝/深拷贝

    老高说,基本功不扎实会在工作中遇到很多的坑,非常同意- 函数定义示例 1.含有返回值 # -*-coding:utf-8-*- def add(a, b):'''两数相加'''sum = a + br ...

  4. C++11 std::shared_ptr的std::move()移动语义底层分析

    std::shared_ptr的std::move()移动语义底层分析 执行std::move()之前: 执行std::move()之后: 结论:一个浅拷贝 sizeof(std::shared_pt ...

  5. android中intent放数据类型,Android Intent传递数据底层分析详细介绍

    Android  Intent传递数据底层分析详细介绍 我们知道在Activity切换时,如果需要向下一个ActivityB传递数据,可以借助Intent对象的putExtra方法. 但是不知各位有没 ...

  6. String的底层分析 (学习笔记)

    StringTable底层分析 String的基本特性 StringPool String的内存分配 字符串的拼接操作 拼接效率的对比 intern()的理解 new String("&qu ...

  7. android 4.4 电池电量管理底层分析(C\C++层)

    参考文献:http://blog.csdn.net/wlwl0071986/article/details/38778897 简介: Linux电池驱动用于和PMIC交互.负责监听电池产生的相关事件, ...

  8. ①、iOS-RAC的开发用法-底层分析以及总结

    iOS RAC系列 ①.iOS-RAC的开发用法-底层分析以及总结 ②.iOS-RAC-核心类分析-RACPassthroughSubscriber订阅者-RACScheduler调度者-RACDis ...

  9. 从底层分析c和类c语言

    转自:http://blog.csdn.net/jggyyhh/article/details/50429886?locationNum=5&fps=1 要想深入理解C语言就不得不要知道几个知 ...

最新文章

  1. Spring 的 Bean 生命周期,11 张高清流程图及代码,深度解析
  2. 新闻媒体的“社会热点事件”催发微博客的诞生
  3. C++ eof()函数陷阱
  4. 官方一步解决各种Windows更新问题
  5. 通过过滤器防止用户通过url访问不在权限内的菜单
  6. 如何把荣耀手机的计算机移动到桌面,华为荣耀怎么把天气预报设置到桌面
  7. Android系统进程间通信(IPC)机制Binder中的Client获得Server远程接口过程源代码分析(2)...
  8. python函数执行shell_6方法,python中执行shell命令
  9. php 正则表达式获取html标签内容_总结Python网络爬虫四大选择器(正则表达式、BS4、Xpath、CSS)...
  10. 剑指offer之矩阵中的最短路径
  11. 入门程序员如何写博客
  12. 软件一定存在修改的余地——《大话Java性能优化》
  13. ISO语言代码(ISO-639)与国家代码(ISO-3166)
  14. layui模板引擎的使用1
  15. java 调度池_定时任务调度池 - 南郭先生Official的个人空间 - OSCHINA - 中文开源技术交流社区...
  16. 复旦提出ObjectFormer,收录CVPR 2022!图像篡改检测新工作!
  17. 博优商业管理系统SQL Anywhere(ASA) 数据库“File is shorter than expected -- transaction rolled back”错误修复
  18. 查询邮件传输日志(exchange2016)
  19. 【Unity3D软硬件】Unity3D与串口通信 SerialPort类完全教程
  20. Cisco Packet Tracer(静态路由+Trunk+VTP协议+单臂路由)

热门文章

  1. DL之PerceptronAdalineGD:基于iris莺尾花数据集利用Perceptron感知机和AdalineGD算法实现二分类
  2. ML/DL之激活函数/求导函数:ML中常用的AF激活函数(step_function、sigmoid、softmax、ReLU等)求导函数等代码实现之详细攻略
  3. 成功解决调用密钥报错4001 加密方式错误
  4. ML之Clustering之K-means:K-means算法简介、应用、经典案例之详细攻略
  5. 成功解决Building wheels for collected packages: dlib Running setup.py bdist_wheel for dlib ... error
  6. 《python机器学习经典实例》Expected 2D array, got 1D array instead和Reshape your data either using array.问题(已解决)
  7. rabbitMQ(二):Fanout Exchange
  8. 前端构建工具gulp之基本介绍
  9. Html中元素的分类
  10. dede_arctype|栏目表