C++中delete[]是如何知道数组大小的
先看一段代码:
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[]是如何知道数组大小的的更多相关文章
- c++: 获取delete[]中的数组大小
看一个小例子: 1 #include <iostream> 2 3 using namespace std; 4 5 class A { 6 public: 7 A() { ...
- [百度]数组A中任意两个相邻元素大小相差1,在其中查找某个数
一.问题来源及描述 今天看了July的微博,发现了七月问题,有这个题,挺有意思的. 数组A中任意两个相邻元素大小相差1,现给定这样的数组A和目标整数t,找出t在数组A中的位置.如数组:[1,2,3,4 ...
- (笔试题)数组A中任意两个相邻元素大小相差1,在其中查找某个数。
题目: 数组A中任意两个相邻元素大小相差1,现给定这样的数组A和目标整数t,找出t在数组A中的位置.如数组:[1,2,3,4,3,4,5,6,5],找到4在数组中的位置. 思路: 很明显,在数组中寻找 ...
- 代码实现:定义一个文件输入流,调用read(byte[] b)方法,将a.txt文件中的内容打印出来(byte数组大小限制为5)
package com.loaderman.test; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; im ...
- delete 和 splice 删除数组中元素的区别
delete 和 splice 删除数组中元素的区别 ` var arr1 = ["a","b","c","d"]; d ...
- OpenCV中Mat与二维数组之间的转换
---恢复内容开始--- 在OpenCV中将Mat(二维)与二维数组相对应,即将Mat中的每个像素值赋给一个二维数组. 全部代码如下: #include <iostream> #inclu ...
- C语言中如何将二维数组作为函数的参数传递
今天写程序的时候要用到二维数组作参数传给一个函数,我发现将二维数组作参数进行传递还不是想象得那么简单里,但是最后我也解决了遇到的问题,所以这篇文章主要介绍如何处理二维数组当作参数传递的情况,希望大家不 ...
- C/C++ 中长度为0的数组
参考文献:http://blog.csdn.net/zhaqiwen/article/details/7904515 近日在看项目中的框架代码时,发现了了一个奇特的语法:长度为0的数组例如 uint8 ...
- SQL中查看数据库各表的大小
SQL中查看数据库各表的大小 编写人:CC阿爸 2014-6-17 在日常SQL数据库的操作中,如何快速的查询数据库中各表中数据的大小. 以下有两种方法供参考: 第一种: create table # ...
随机推荐
- Linux服务器集群系统(四)--转
引用地址:http://www.linuxvirtualserver.org/zh/lvs4.html LVS集群的负载调度 章文嵩 (wensong@linux-vs.org) 2002 年 5 月 ...
- Linux服务器集群系统(二)--转
引用地址:http://www.linuxvirtualserver.org/zh/lvs2.html LVS集群的体系结构 章文嵩 (wensong@linux-vs.org) 2002 年 4 月 ...
- PEAR:使用PHPDoc轻松建立你的PEAR文档
对于一个开发人员,文档总是最感到头疼的事情之一.而且,很可能你对待文档会采取截然不同的2种态度: 当你使用别人的代码库的时候,最希望得到的是它的技术文档,尤其是当时间很紧,而你又不得不硬着头皮去读那些 ...
- Design Mode 之 行为模式
行为型模式,共十一种:策略模式.模板方法模式.观察者模式.迭代子模式.责任链模式.命令模式.备忘录模式.状态模式.访问者模式.中介者模式.解释器模式. 看看这11中模式的关系,大致可分为四类:(1) ...
- C中存储类、链接和内存管理
在C语言中,有5种不同的存储类型,即存储类.在介绍存储类之前,需要首先简单介绍几个术语.如下: 作用域:描述程序中可以访问一个标识符的一个或多个区域.一个C变量的作用域可以是代码块作用域.函数原型作用 ...
- spring WebServiceTemplate 调用 axis1.4 发布的webservice
前言: 最近在开发中需要调用对方的 webservice服务,按照现有的技术,本应该是一件很简单的事情,只需要拿到wsdl文件,生成客户端代码即可,但是,对方的webservice服务是06年用ax ...
- TikaEntityProcessor 各种示例
1. <dataConfig> <dataSource type="BinFileDataSource" /> <script><![CD ...
- 1. windows下作为应用程序启动apache的方法
1. 具体步骤如下:(文章末尾附加:Apache 2.2.17下载路径) 步骤一 :Cmd打开命令行窗口,切换到apache安装目录下 cd C:\MAS\TRSMAS\win31\apache\b ...
- Redis缓存异常的容错实现方法( .net)
using DotNet.Log; /// <summary> /// Redis缓存辅助类 /// /// 修改纪录 /// /// 2015-10-26 版本:1.0 SongBiao ...
- FormsAuthentication与Session超时时间不一的解决方法
因为FormsAuthentication 和 Session 的cookies不一样,造成了FormsAuthentication 还能进入,而 session已经超时的问题. 最好的办法就是当让F ...