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[]的区别的主要内容,如果未能解决你的问题,请参考以下文章
PHP中new self()和new static()的区别探究