博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
new和new[]的区别
阅读量:4458 次
发布时间:2019-06-08

本文共 2628 字,大约阅读时间需要 8 分钟。

背景

日常查看qq消息的时候,看到群里有位同学问到

在处理怎样让对象只能生成在堆上而不能生成在栈上的问题的时候,发现当私有化析构函数以后 , 为什么调用 operator new [] 会报错?

把问题翻译成代码

class  A{	friend class B;public:	 A();private:	~ A();}; A:: A(){	 cout << "A()" << endl;} A::~ A(){	 cout << "~A()" << endl;}int main(){	A * test1 = new A[]; //使用new []会编译报错        A * test2 = new A;   //但是使用 new 就没有问题     	return 0;}

  

原因

这个问题,我没有碰到过,但是有一本书《C++反汇编与逆向技术揭秘》,书上从汇编角度讲过 new[]/new 和delete[]/delete,也就是new/new[] 的时候汇编上面的表现是不一样的(可以配合着书本在本地IDE上反汇编看看),
 
下面的例子主要是为了说明 new和new[] 在汇编层面的区别
new的反汇编

 

new[]的反汇编

 

接下来解释一下两个汇编代码的意思
 
A * testA = new A; 压入待分配的类对象所需要的空间 00992A9D  push        1  调用new函数进行分配空间 00992A9F  call        operator new (0991339h)  由于new函数是__cdecl调用类型,所以由调用者负责恢复堆栈平衡 00992AA4  add         esp,4  将分配的地址存放在临时变量[ebp-0F8h]中 00992AA7  mov         dword ptr [ebp-0F8h],eax  [ebp-4]保存申请堆空间的次数 00992AAD  mov         dword ptr [ebp-4],0  检测堆空间是否申请成功 00992AB4 cmp dword ptr [ebp-0F8h],0 如果申请失败的话,就跳过构造函数,跳到0x0992AD0h将存放this指针的临时变量赋值为0 00992ABB je main+70h (0992AD0h)
00992ABD mov ecx,dword ptr [ebp-0F8h] 00992AC3 call A::A (0991325h) 00992AC8 mov dword ptr [ebp-118h],eax 00992ACE jmp main+7Ah (0992ADAh) 00992AD0 mov dword ptr [ebp-118h],0 00992ADA mov eax,dword ptr [ebp-118h] 00992AE0 mov dword ptr [ebp-0ECh],eax 00992AE6 mov dword ptr [ebp-4],0FFFFFFFFh 00992AED mov ecx,dword ptr [ebp-0ECh] 00992AF3 mov dword ptr [testA],ecx

  

B * testB = new B[2];00992AF6  push        6  00992AF8  call        operator new[] (09913CAh)  00992AFD  add         esp,4  00992B00  mov         dword ptr [ebp-110h],eax  00992B06  mov         dword ptr [ebp-4],1  00992B0D  cmp         dword ptr [ebp-110h],0  00992B14  je          main+0F0h (0992B50h)  00992B16  mov         eax,dword ptr [ebp-110h]  00992B1C  mov         dword ptr [eax],2  00992B22  push        offset B::~B (09911FEh)  00992B27  push        offset B::B (0991456h)  00992B2C  push        2  00992B2E  push        1  00992B30  mov         ecx,dword ptr [ebp-110h]  00992B36  add         ecx,4  00992B39  push        ecx  00992B3A  call        `eh vector constructor iterator' (0991168h)  00992B3F  mov         edx,dword ptr [ebp-110h]  00992B45  add         edx,4  00992B48  mov         dword ptr [ebp-118h],edx  00992B4E  jmp         main+0FAh (0992B5Ah)  00992B50  mov         dword ptr [ebp-118h],0  00992B5A  mov         eax,dword ptr [ebp-118h]  00992B60  mov         dword ptr [ebp-104h],eax  00992B66  mov         dword ptr [ebp-4],0FFFFFFFFh  00992B6D  mov         ecx,dword ptr [ebp-104h]  00992B73  mov         dword ptr [testB],ecx

  

 

参考:https://www.cnblogs.com/chaoguo1234/p/3213532.html

 

 

 

转载于:https://www.cnblogs.com/hanhuihanhui/p/9491163.html

你可能感兴趣的文章
关于互联网的一些数据
查看>>
数据预处理:独热编码(One-Hot Encoding)
查看>>
python将对象名的字符串类型,转化为相应对象的操作方法
查看>>
【NLP新闻-2013.06.03】New Book Where Humans Meet Machines
查看>>
mongodb安装4.0(rpm)
查看>>
DispatcherServlet的url mapping为“/”时,对根路径访问的处理
查看>>
备忘pwnable.kr 之passcode
查看>>
好久没敲代码了,手有点生——一个小小的时钟
查看>>
运算符 AS和IS 的区别
查看>>
(转)详解C中volatile关键字
查看>>
easyui时的时间格式yyyy-MM-dd与yyyy-MM-ddd HH:mm:ss
查看>>
专题:动态内存分配----基础概念篇
查看>>
Codeforces Round #426 (Div. 2) (A B C)
查看>>
The Most Simple Introduction to Hypothesis Testing
查看>>
UVA10791
查看>>
P2664 树上游戏
查看>>
jQuery 停止动画
查看>>
Sharepoint Solution Gallery Active Solution时激活按钮灰色不可用的解决方法
查看>>
MyBatis Generator去掉生成的注解
查看>>
教你50招提升ASP.NET性能(二十二):利用.NET 4.5异步结构
查看>>