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 # ...
随机推荐
- APP快速通过苹果AppStore审核九大诀窍
[IT168技术]对于移动应用开发者来说, 最令人沮丧的可能莫过于辛辛苦苦开发的应用, 没能通过苹果AppStore的审核,或者在应用更新时遭遇下架.苹果的AppStore的审核流程和标准, 一向不透 ...
- EF 预热
由于EF第一次加载比较慢,所以要对EF进行一次初始化的加载,类似第一次打开网页很慢,但第二次打开都很快了的原理一样:第一次把所有静态的图片和JS缓存到本地了:当第二次打开的时候都不需要再去下载这些东西 ...
- js json与对象的相互转换
var str = '{ "name": "cxh", "sex": "man" }'; //JSON字符串:var o ...
- SQL Server 表和索引存储结构
在上一篇文章中,我们介绍了SQL Server数据文件的页面类型,系统通过96个字节的头部信息和系统表从逻辑层面上将表的存储结构管理起来,具体到表的存储结构上,SQL Server引入对象.分区.堆或 ...
- Spring MVC学习笔记 01
applicationcontext.xml的配置 <?xml version="1.0" encoding="UTF-8" ?> <bean ...
- 标签云 - jqcloud 用法
html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF- ...
- 【python,threading】python多线程
使用多线程的方式 1. 函数式:使用threading模块threading.Thread(e.g target name parameters) import time,threading def ...
- 九 AIDL
多进程 多线程 优点 安全 稳定 扩大内存空间 节约CPU时间 AIDL=Android Interface definition language 使用情况:做一个下载,不想让你的下载拖垮你 ...
- vb.net机房收费系统之组合查询
我个人一直认为,组合查询是机房收费系统的一个难点,尤其是用到三层之后,如果要为组合查询中的每一个查询建立一个显然是太麻烦了. 下面介绍一下我的方法,对大家起个参考作用. 我将该表中可输入的内容定义为一 ...
- jQuery选择器之子元素过滤选择器Demo
测试代码: 07-子元素过滤选择器.html <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" & ...