码迷,mamicode.com
首页 > 其他好文 > 详细

new和new[]的区别

时间:2018-09-24 12:04:37      阅读:194      评论:0      收藏:0      [点我收藏+]

标签:class   意思   ons   friend   类对象   opera   例子   报错   析构   

背景

日常查看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

 

 

 

new和new[]的区别

标签:class   意思   ons   friend   类对象   opera   例子   报错   析构   

原文地址:https://www.cnblogs.com/hanhuihanhui/p/9491163.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!