先看一段代码:

int main(void)

{

int *pI = new int;

int *pArray = new int[10];

int size = *(pArray-1);

delete pI;

delete [] pArray; // delete是如何知道pArray数组大小的?

return 0;

}

看反编译后代码,没能直接找到答案,于是在网上搜索发现这样一篇文章:《Mismatching scalar and vector new and delete》。文章中说明了内存布局大概是这样:

这个结论肯定是正确的,但是我却没能在内存中找到这个记录数组大小的地址。再看反编译代码,例子中分别new了一个对象和一个数组,例子最后使用delete[]分别删除了这两个对象。从C++角度来说,第一个delete是scalar "delete",第二个delete [] 是vector "delete"。这两种delete调用应该不一样才对,但从反编译代码看,两处调用完全相同。

; int __cdecl main()

_main proc near

var_5C= dword ptr -5Ch

var_58= dword ptr -58h

p= dword ptr -54h

var_50= dword ptr -50h

size= dword ptr -0Ch

push ebp

mov ebp, esp

sub esp, 5Ch

push ebx

push esi

push edi

push 4 ; size

call j_??2@YAPAXI@Z ; operator new(uint)

mov [ebp+var_5C], eax

mov eax, [ebp+var_5C]

mov [ebp+pI], eax

nop

push 28h ; size

call j_??2@YAPAXI@Z ; operator new(uint)

mov [ebp+var_58], eax

mov eax, [ebp+var_58]

mov [ebp+pArray], eax

nop

mov eax, [ebp+pArray]

mov ecx, [eax-4]

mov [ebp+size], ecx

nop

mov eax, [ebp+pI]

mov [ebp+p], eax

mov ecx, [ebp+p]

push ecx ; p

call j_??3@YAXPAX@Z ; operator delete(void *)

nop

mov eax, [ebp+pArray]

mov [ebp+var_50], eax

mov ecx, [ebp+var_50]

push ecx ; p

call j_??3@YAXPAX@Z ; operator delete(void *)

xor eax, eax

pop edi

pop esi

pop ebx

mov esp, ebp

pop ebp

retn

_main endp

结论:

  • 通过观察"new"调用了HeapAlloc函数,而这一函数使用可以将内存分配情况用结构体保存起来,"delete"估计就是通过这一结构体得到数组大小的。也就是说C++这一语法特点是借用了HeapAlloc等函数对Windows堆内存的管理方式实现的。

未知&待研究:

  • scalar "new" 与 vector "delete []"出现不匹配的使用时究竟会不会出现问题
  • 通过反编译验证结论。尤其是"delete []"

C++中delete[]是如何知道数组大小的的更多相关文章

  1. c++: 获取delete[]中的数组大小

    看一个小例子: 1 #include <iostream> 2   3 using namespace std; 4   5 class A { 6 public: 7     A() { ...

  2. [百度]数组A中任意两个相邻元素大小相差1,在其中查找某个数

    一.问题来源及描述 今天看了July的微博,发现了七月问题,有这个题,挺有意思的. 数组A中任意两个相邻元素大小相差1,现给定这样的数组A和目标整数t,找出t在数组A中的位置.如数组:[1,2,3,4 ...

  3. (笔试题)数组A中任意两个相邻元素大小相差1,在其中查找某个数。

    题目: 数组A中任意两个相邻元素大小相差1,现给定这样的数组A和目标整数t,找出t在数组A中的位置.如数组:[1,2,3,4,3,4,5,6,5],找到4在数组中的位置. 思路: 很明显,在数组中寻找 ...

  4. 代码实现:定义一个文件输入流,调用read(byte[] b)方法,将a.txt文件中的内容打印出来(byte数组大小限制为5)

    package com.loaderman.test; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; im ...

  5. delete 和 splice 删除数组中元素的区别

    delete 和 splice 删除数组中元素的区别 ` var arr1 = ["a","b","c","d"]; d ...

  6. OpenCV中Mat与二维数组之间的转换

    ---恢复内容开始--- 在OpenCV中将Mat(二维)与二维数组相对应,即将Mat中的每个像素值赋给一个二维数组. 全部代码如下: #include <iostream> #inclu ...

  7. C语言中如何将二维数组作为函数的参数传递

    今天写程序的时候要用到二维数组作参数传给一个函数,我发现将二维数组作参数进行传递还不是想象得那么简单里,但是最后我也解决了遇到的问题,所以这篇文章主要介绍如何处理二维数组当作参数传递的情况,希望大家不 ...

  8. C/C++ 中长度为0的数组

    参考文献:http://blog.csdn.net/zhaqiwen/article/details/7904515 近日在看项目中的框架代码时,发现了了一个奇特的语法:长度为0的数组例如 uint8 ...

  9. SQL中查看数据库各表的大小

    SQL中查看数据库各表的大小 编写人:CC阿爸 2014-6-17 在日常SQL数据库的操作中,如何快速的查询数据库中各表中数据的大小. 以下有两种方法供参考: 第一种: create table # ...

随机推荐

  1. 依赖注入框架Autofac的简单使用

    http://www.cnblogs.com/liping13599168/archive/2011/07/16/2108209.html Autofac是一款IOC框架,比较于其他的IOC框架,如S ...

  2. IOPS

    http://www.cnblogs.com/sink_cup/archive/2012/09/14/ssd_iops_sql_nosql.html http://www.techrepublic.c ...

  3. IFormatProvider,ICustomFormatter,IFormattable总结

    IFormatProvider中 public object GetFormat(Type formatType); 该方法主要用于获取一个 ICustomFormatter接口的实例 ICustom ...

  4. Golang学习 - fmt 包

    ------------------------------------------------------------ // Print 将参数列表 a 中的各个参数转换为字符串并写入到标准输出中. ...

  5. 转:关掉Archlinux中烦人的响铃

    http://www.0597seo.com/?p=461 F**K,在Archlinux中,每当在听音乐,声音开得挺大的,忽然在控制台输错了命令,那可恶的该死的警告声猛的一下总是吓的我精神晃晃(这是 ...

  6. spark1.2.0编译

    spark 有三种编译方式:SBT.MAVEN.make-distribution.sh.SBT.MAVEN两种方式打出来的包比较大,不适合部署使用.因此我们通常使用第三种方式打包. ./make-d ...

  7. WPF/Silverlight Layout 系统概述——Arrange(转)

    Arrange过程概述 普通基类属性对Arrange过程的影响 我们知道Measure过程是在确定DesiredSize的大小,以便Arrange过程参考这个DesiredSize,确定给MyPane ...

  8. 【Android 界面效果42】如何自定义字体

    项目里要统一用设计师的字体,android:typeface只支持系统三种字体.有什么比较好的做法? 你需要为整个应用替换自定义字体. 解决方案 1)Android默认方法 #1 你可以通过ID查找到 ...

  9. 重构4-Push Down Method(方法下移)

    我们介绍了将方法迁移到基类以供多个子类使用的上移方法重构,今天我们来看看相反的操作.重构前的代码如下: public abstract class Animal { public void Bark( ...

  10. C++中模板函数或模板类中关键词class和typename

    ##区别 基本上来说,class和typename几乎没有区别.在可以使用class的地方都可以使用typename,在使用typename的地方也几乎可以使用class. 可以看出我加黑了两个子:几 ...