当你写下new和delete的时候,到底发生了什么事呢,让我们来做个试验看看。
写一段小代码:
- class a
- {
- public:
a() { foo(); } int foo() { return 0; } ~a() { bar(); } int bar() { return 1; } }; int _tmain(int argc, _TCHAR* argv[]) { a* tmp = new a(); delete tmp; return 0; }
在main函数的第一句下断点,调试,然后开汇编窗口输出结果:
- int _tmain(int argc, _TCHAR* argv[])
- {
- 004113F0 push ebp
- 004113F1 mov ebp,esp
- 004113F3 push 0FFFFFFFFh
- 004113F5 push offset __ehhandler$_wmain (41478Eh)
- 004113FA mov eax,dword ptr fs:[00000000h]
- 00411400 push eax
- 00411401 sub esp,100h
- 00411407 push ebx
- 00411408 push esi
- 00411409 push edi
- 0041140A lea edi,[ebp-10Ch]
- 00411410 mov ecx,40h
- 00411415 mov eax,0CCCCCCCCh
- 0041141A rep stos dword ptr es:[edi]
- 0041141C mov eax,dword ptr [___security_cookie (418000h)]
- 00411421 xor eax,ebp
- 00411423 push eax
- 00411424 lea eax,[ebp-0Ch]
- 00411427 mov dword ptr fs:[00000000h],eax
-
- 0041142D push 1
- 0041142F call operator new (4111A4h)
- 00411434 add esp,4
- 00411437 mov dword ptr [ebp-0F8h],eax
- 0041143D mov dword ptr [ebp-4],0
- 00411444 cmp dword ptr [ebp-0F8h],0
- 0041144B je wmain+70h (411460h)
- 0041144D mov ecx,dword ptr [ebp-0F8h]
- 00411453 call a::a (41101Eh)
- 00411458 mov dword ptr [ebp-10Ch],eax
- 0041145E jmp wmain+7Ah (41146Ah)
- 00411460 mov dword ptr [ebp-10Ch],0
- 0041146A mov eax,dword ptr [ebp-10Ch]
- 00411470 mov dword ptr [ebp-104h],eax
- 00411476 mov dword ptr [ebp-4],0FFFFFFFFh
- 0041147D mov ecx,dword ptr [ebp-104h]
- 00411483 mov dword ptr [ebp-14h],ecx
-
- 00411486 mov eax,dword ptr [ebp-14h]
- 00411489 mov dword ptr [ebp-0E0h],eax
- 0041148F mov ecx,dword ptr [ebp-0E0h]
- 00411495 mov dword ptr [ebp-0ECh],ecx
- 0041149B cmp dword ptr [ebp-0ECh],0
- 004114A2 je wmain+0C9h (4114B9h)
- 004114A4 push 1
- 004114A6 mov ecx,dword ptr [ebp-0ECh]
- 004114AC call a::`scalar deleting destructor' (41117Ch)
- 004114B1 mov dword ptr [ebp-10Ch],eax
- 004114B7 jmp wmain+0D3h (4114C3h)
- 004114B9 mov dword ptr [ebp-10Ch],0
-
- 004114C3 xor eax,eax
- }
- 004114C5 mov ecx,dword ptr [ebp-0Ch]
- 004114C8 mov dword ptr fs:[0],ecx
- 004114CF pop ecx
- 004114D0 pop edi
- 004114D1 pop esi
- 004114D2 pop ebx
- 004114D3 add esp,10Ch
- 004114D9 cmp ebp,esp
- 004114DB call @ILT+345(__RTC_CheckEsp) (41115Eh)
- 004114E0 mov esp,ebp
- 004114E2 pop ebp
- 004114E3 ret
前面一片调整stack,插入安全代码,设置异常处理等的操作不是今天我们要说的重点,直接跳到a* tmp = new a();这一句产生的反汇编:
- 0041142F call operator new (4111A4h)
我们很明确的看到调用了一个函数operator new。继续跟进operator new看到底做了什么事情:
- void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
- {
- void *p;
- while ((p = malloc(size)) == 0)
- if (_callnewh(size) == 0)
- {
- static const std::bad_alloc nomem;
- _RAISE(nomem);
- }
-
- return (p);
- }
很意外吧,其实operator new函数就做了那么一件事情:调用malloc函数分配内存。有没有负责调用构造函数?这个真没有。。。