(在 vc debug模式下 )
double *p1 = new double ; |
00411A6E push 8 00411A70 call operator new (4111B8h) 00411A75 add esp,4 00411A78 mov dword ptr [ebp-104h],eax 00411A7E mov eax,dword ptr [ebp-104h] 00411A84 mov dword ptr [p1],eax |
|
double *p2 = new double (3.0); |
00411A87 push 8 00411A89 call operator new (4111B8h) 00411A8E add esp,4 00411A91 mov dword ptr [ebp-0F8h],eax 00411A97 cmp dword ptr [ebp-0F8h],0 00411A9E je memory_func5+6Ch (411ABCh) 00411AA0 mov eax,dword ptr [ebp-0F8h] 00411AA6 fld qword ptr [__real@4008000000000000 (416650h)] 00411AAC fstp qword ptr [eax] 00411AAE mov ecx,dword ptr [ebp-0F8h] 00411AB4 mov dword ptr [ebp-10Ch],ecx 00411ABA jmp memory_func5+76h (411AC6h) 00411ABC mov dword ptr [ebp-10Ch],0 00411AC6 mov edx,dword ptr [ebp-10Ch] 00411ACC mov dword ptr [p2],edx |
|
class AClass1 { };
AClass1 *pC1 = new AClass1; |
00413D3E push 1 00413D40 call operator new (4111B8h) 00413D45 add esp,4 00413D48 mov dword ptr [ebp-11Ch],eax 00413D4E mov eax,dword ptr [ebp-11Ch] 00413D54 mov dword ptr [ebp-2Ch],eax |
|
class AClass2 { public : AClass2(){} };
AClass2 *pC2 = new AClass2; |
00413D57 push 1 00413D59 call operator new (4111B8h) 00413D5E add esp,4 00413D61 mov dword ptr [ebp-104h],eax 00413D67 mov dword ptr [ebp-4],0 00413D6E cmp dword ptr [ebp-104h],0 00413D75 je memory_func5+0EAh (413D8Ah) 00413D77 mov ecx,dword ptr [ebp-104h] 00413D7D call AClass::AClass (411212h) 00413D82 mov dword ptr [ebp-13Ch],eax 00413D88 jmp memory_func5+0F4h (413D94h) 00413D8A mov dword ptr [ebp-13Ch],0 00413D94 mov eax,dword ptr [ebp-13Ch] 00413D9A mov dword ptr [ebp-110h],eax 00413DA0 mov dword ptr [ebp-4],0FFFFFFFFh 00413DA7 mov ecx,dword ptr [ebp-110h] 00413DAD mov dword ptr [ebp-38h],ecx |
从上面 4个例子可以看到,在 new 操作符的背后,编译器做了两件事 :
- 计算 new后申请的数据的大小,然后调用函数 operator new开辟空间
- 调用相应得构造函数。
当然,在很多情况下,步骤 2都不需要,比如是基本数据类型,或类未写任何构造函数。
事实上,我们完全可以自己手工调用函数实现上面两个过程。
例如:
AClass2 *pC1 = new AClass2; delete pC1; |
AClass2 *pC2 = (AClass2*)operator new (sizeof (AClass2)); ::new (pC2) AClass2;
pC2->~AClass2(); delete ((void *)pC2); |
事实上, vector和 CArray内部需要扩大数组时都采用第二种方法,先申请数组所需的空间,然后对新元素在指定地方调用构造函数。
事实上,在 delete时也会有两个过程:
- 调用类的析构函数
调用 operator delete 函数释放内存