new和new[]的区别

Posted hanhuihanhui

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了new和new[]的区别相关的知识,希望对你有一定的参考价值。

背景

日常查看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[]的区别的主要内容,如果未能解决你的问题,请参考以下文章

JS构造函数加new与不加new的区别?

PHP中new self()和new static()的区别探究

new和new[]的区别

Java中newInstance()和new()区别

php 小知识随手记 new self() 和new static()作用和区别

new int[0] 和 new int[] 之间有啥区别吗[重复]