先看一段代码:

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. java.net.SocketException四大异常解决方案【转】

    java.net.SocketException如何才能更好的使用呢?这个就需要我们先要了解有关这个语言的相关问题.希望大家有所帮助.那么我们就来看看有关java.net.SocketExceptio ...

  2. 40多个关于人脸检测/识别的API、库和软件

    英文原文:List of 40+ Face Detection / Recognition APIs, libraries, and software 译者:@吕抒真 译文:链接 自从谷歌眼镜被推出以 ...

  3. linux学习资料

    鸟哥的Linux私房菜 基础学习篇(第三版)    http://book.51cto.com/art/201007/211888.htm 鸟哥的Linux私房菜——服务器架设篇    http:// ...

  4. Linux scp 使用详解

    一般情况,本地网络跟远程网络进行数据交抱,或者数据迁移,常用的有三种方法,一是ftp,二是wget /fetch 三是,rsync 大型数据迁移用rysync,其次用fetch/wget ,最次是ft ...

  5. QQ会员AMS平台PHP7升级实践

    作者:徐汉彬链接:https://zhuanlan.zhihu.com/p/21493018来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. QQ会员活动运营平台(AMS ...

  6. LeetCode9 Palindrome Number

    题意: Determine whether an integer is a palindrome. Do this without extra space.  (Easy) 分析: 自己考虑的方法是利 ...

  7. what is docker

    尽管之前久闻Docker的大名了,但是天资愚钝,对其到底是个啥东西一直摸不清,最近花了一段时间整理了一下,算是整理出一点头绪来. 官网的介绍是这样的: Docker is an open platfo ...

  8. 使用NuGet加载包,发现加载的dll都是最新版,原来少加了参数[-Version]

    使用NuGet获取AutoMapper 发现无法正确加载包,项目版本是3.5,获取的dll版本较高,查资料发现可以通过 “-Version” 指定加载包版本 http://www.mamicode.c ...

  9. Burn the Linked Camp(bellman 差分约束系统)

    Burn the Linked Camp Time Limit: 2 Seconds      Memory Limit: 65536 KB It is well known that, in the ...

  10. 1.5.8 语言分析器(Analyzer)

    语言分析器(Analyzer) 这部分包含了分词器(tokenizer)和过滤器(filter)关于字符转换和使用指定语言的相关信息.对于欧洲语言来说,tokenizer是相当直接的,Tokens被空 ...