Behind new and delete in C + +

Source: Internet
Author: User
Tags scalar

Transferred from: http://www.cppblog.com/weiym/archive/2013/11/17/204292.html

The behavior behind new in C + + has previously been written to understand the behavior behind new in C + +, but it is only a generalities, no conclusive evidence, what do the C + + compilers do behind the scenes from a compilation point of view? Our code is simple, as follows: #include <iostream> class A{public:virtual void print (){std::cout <<;}virtual ~a (){std::cout << "~a ()";}}; Class B:public A{public:virtual void print (){std::cout <<;}}; int _tmain (int argc, _tchar* argv[]) {A * p = new B ();p->print ();delete p;return 0;}  I use WinDbg to see the assembly code generated by the main function as follows:   newtest!wmain:00aa1020              push    esi00aa1021 6a04            push    4 00aa1023 e8b403 0000      call    newtest!operator New (00AA13DC)//Call operator new allocate a space of 4 bytes 00aa1028 83c404 &nb Sp        add     esp,400aa102b 85c0            test   &NBSP ; eax,eax00aa102d 740a            je      newtest!wmain+0x19 (00aa1039) 00aa10 2f c7005421aa00    mov     DWORD ptr [Eax],offset newtest! B:: ' vftable ' (00aa2154)//write the virtual table address to the first 4 bytes of the object address (virtual table pointer) 00aa1035 8bf0            mov     esi,eax00aa1037 eb02            jmp     newtest!wmain+0x1b (00aa103b) 00aa1039 33f 6            xor     ESI,ESI00AA103b 8b06            mov     Eax,dword ptr [esi]00aa103d 8b10       & nbsp    mov     Edx,dword ptr [eax]00aa103f 8bce            mov     ecx,esi00aa1041 ffd2            call   &NBSP;EDX//calling the first function within a virtual table print00aa1043 8b06 &nbsp ;          mov     Eax,dword ptr [esi]00aa1045 8b5004         &NBSP;M OV     Edx,dword ptr [eax+4]00aa1048 6a01            push   &NBSP;100AA104A 8 BCE            mov     ecx,esi00aa104c ffd2           &NB Spcall EdX//calls the second function within a virtual table (destructor)00aa104e 33c0 xor eax,eax00aa1050 5e Pop esi00aa1051 c3 ret00aa1052 cc int 3 from the above code we can see that we construct a total of 4 bytes of the B object, and these four bytes contain the object's virtual table pointer, for C + + object memory layout, for C + + object memory layout, you can see my this articleExplore the C + + object model. At the same time, we can see that C + + is really a virtual table to achieve polymorphism.  The above code also tells us why we cannot implement polymorphism in constructors by calling virtual functions. Because the virtual table is generated in the constructor of the final derived class, the virtual table is not generated when the base class constructor is executed.   0:000> u 00aa13dcnewtest!operator new:00aa13dc ff25cc20aa00    jmp     DWORD ptr [Newtest!_imp_?? 2YAPAXIZ (00aa20cc)]  inside is a direct jump:0:000> u poi (00aa20cc) l10msvcr90!operator new:74603e99 8bff            mov     edi,edi74603e9b/             push &nbsp ;  ebp74603e9c 8bec            mov     ebp,esp74603e9e 83ec0c     &NB Sp    sub     ESP,0CH74603EA1 eb0d           &NBSP;JMP     Msvcr90!ope Rator new+0x17 (74603eb0) 74603ea3 ff7508          push    dword ptr [ebp+8]74603ea6 E85 9DCFBFF      call   &NBSP;MSVCR90!_CALLNEWH (745c1b04) 74603eab i           & nbsp  pop     ECX74603EAC 85c0            test    eax,eax74603eae 740f & nbsp     &NBsp    je      msvcr90!operator new+0x26 (74603EBF) 74603eb0 ff7508           Push    dword ptr [ebp+8] 74603eb3 e887feffff Call Msvcr90!malloc (74603d3f)74603eb8-pop ecx74603eb9 85c0 test Eax,eax74603ebb 74e6 JE msvcr90!opera Tor new+0xa (74603EA3) 74603ebd C9 Leavewe can see that operator new is finally called malloc, and if you go further down, you will find that malloc is calling kernel32! HeapAlloc, and HeapAlloc called ntdll!.Rtlallocateheap, on the heap layout and allocation algorithm, you can seesoftware Debugging for Zhang Banque the behavior behind the new operator is demonstrated above:First call operator new allocate space, we can overload operator new, define our own memory allocation algorithmThe constructor is then called on the allocated space to create the object, and the virtual table pointer may be assigned inside the constructor.  Next we look at the behavior behind the delete. we see that the delete call is the second function in the virtual table, and we first look at the contents of the virtual tables:0:000> DPS 00aa215400aa2154  00aa1010 newtest! B::p rint [f:\test\newtest\newtest\newtest.cpp @ 26]00aa2158  00aa1060 newtest! B:: ' scalar deleting destructor ' 00aa215c  0000000000aa2160  0000004800aa2164  00000000  There are 2 functions in the virtual table above, one is print, and the other is destructor, we look at the contents of the second function:0:000> u 00aa1060  l10newtest! B:: ' scalar deleting destructor ': 00aa1060              push    esi00aa1061 8BF1            mov     esi,ecx00aa1063 c7064821aa00    mov   &NBSP ; DWORD ptr [Esi],offset newtest! A:: ' vftable ' (00aa2148) 00aa1069 a15820aa00      mov     Eax,dword ptr [Newtest!_imp_?coutstd (00 aa2058)]00aa106e              push    eax00aa106f e84c010000      call    NewTest!std::operator<<<std::char_traits<char> > (00aa11c0) 00aa1074 83c404          add     esp,400aa1077 f644240801      test    byte ptr [esp+8],100aa107c 7409 &N Bsp          je      newtest! B:: ' scalar deleting destructor ' +0x27 (00aa1087) 00aa107e              push   &NB sp;esi00aa107f e806030000      call    newtest!operator Delete (00aa138a) 00aa1084 83c404          add     esp,400aa1087 8bc6            mov     eax,esi00aa1089 5e              pop     esi00aa108a c20400     &NB Sp    ret     4we can see that the imaginary table is B.Scalar deleting destructor, it contains two parts of code, one is the code of the destructor that we really define, and part of it is operator delete (operator delete will call free, and the free call kernel32! HeapFree). Here'sScalar deleting destructor is obviously not a destructor for B ~b (), which is a function that the compiler helped me to use for delete type B objects.let's look at the pointer to the array type, how the C + + compiler handles it, and change the code to the following:int _tmain (int argc, _tchar* argv[]) {A * p = new A[10];delete []p;return 0;The following is the generated assembly code: newtest!wmain:01181030 6a2c push 2Ch 01181032 e8c4030000 call Newtest!operator new[] (0            11813FB)//via operator new Assignment 44 own 01181037 83c404 add esp,40118103a 85c0 test eax,eax0118103c 7444 Je newtest!wmain+0x52 (01181082) 0118103e-in-a-push ESI0118103f 6810101801 Push offset newtest! Destructors for A::~a (01181010)//a01181044 6800111801 Push offset newtest! A::a (01181100)//a constructor01181049 6a0a push 0Ah//100118104b 8d7004 Lea Esi,[eax+4]//crossed the first four bytes0118104e 6A04 Push 4//object size01181050 The//esi of the object list (spanning the first four bytes) .01181051 c7000a000000 mov dword ptr [eax],0ah//Head four bytes write to List of objects (x)01181057 e812040000 call newtest! ' eh Vector constructor iterator ' (0118146e)0118105c 85f6 Test esi,esi0118105e 7421 JE newtest!wmain+0x51 (01181081)01181060 837efc00 cmp dword ptr [esi-4],0//Determine whether the number of objects is 001181064 8D46FC Lea Eax,[esi-4]//address with number of objects saved to eax01181067 740f JE newtest!wmain+0x48 (01181078)01181069 8b06 mov eax,dword ptr [esi]//Take A's virtual table address0118106b 8b5004 mov edx,dword ptr [eax+4]//second function in virtual table0118106e 6a03 Push 301181070 8BCE mov ecx,esi01181072 ffd2 call edx01181074 5e pop esi01181075 33c0 xor eax,eax01181077 c3 ret Focus look aboveRedcode, we can see that in the new array, the compiler helps us do the following things:(1) Call an array of operator new[] to allocate memory, size 4 + sizeof (object) * Count, where the first four bytes are the number of objects (2) called newtest! ' eh Vector constructor iterator (pArr Ayaddress, sizeof (object),   object_count, pfunconstructor, pfundestructor),  which  pfundestructor is a destructor,  pfunconstructor is a constructor,  object_count is the number of objects,  sizeof (object) is the object size, Parrayaddress is the starting address. ,   below we disassemble  newtest! ' eh vector constructor iterator: 0:000> u 0118146e l50newtest! ' eh vector Constructor iterator ': 0118146e 6a10            push    10h01181470 6890221801 &nbs P    push    offset newtest!__rtc_tzz+0x8 (01182290) 01181475 e8d2040000      call   &NBSP;NEWTEST!__SEH_PROLOG4 (0118194c) 0118147a 33c0            xor     EAX, eax0118147c 8945e0          mov     DWORD ptr [ebp-20h],eax0118147f 8945fc   &NBSP ;      mov     DWORD ptr [ebp-4],eax01181482 8945e4          mov     DWORD ptr [ebp-1ch],eax01181485 8b45e4 &nb Sp        mov     Eax,dword ptr [ebp-1ch]//Temporary count, initial 001181488 3b4510       &NBSP ;  cmp     Eax,dword ptr [ebp+10h]  //Compare temporary count and number of objects 0118148b 7d13           &NBSP ; jge     newtest! ' eh Vector constructor iterator ' +0x32 (011814a0)//exit loop 0118148d 8b7508   &NB If the temporary count is greater than the number of objects Sp      mov     Esi,dword ptr [ebp+8]//Save first parameter (start address) to esi01181490 8BCE            mov     Ecx,esi//Assign this pointer to ECX01181492 ff5514call DWORD ptr [ebp+14h]//calling constructor01181495 03750c          add     Esi,dword ptr [ebp+0ch]//Move pointer, plus object size 01181498 897508          mov     DWORD ptr [Ebp+8],esi//Save new object address to the first parameter 0118149b ff45e4     &NB Sp    inc     DWORD ptr [ebp-1ch]//Increase temporary count 0118149e ebe5           &NBSP;JMP &nbs P   newtest! ' eh Vector constructor iterator ' +0x17 (01181485) 011814a0 c745e001000000  mov     DWORD ptr [ Ebp-20h],1011814a7 c745fcfeffffff  mov     DWORD ptr [ebp-4],0fffffffeh011814ae e808000000     & Nbsp;call    newtest! ' eh Vector constructor iterator ' +0x4d (011814BB) 011814b3 e8d9040000       Call   &NBSP;NEWTEST!__SEH_EPILOG4 (01181991) 011814b8 c21400          ret     14h& nbsp;  we can see that the newtest! ' eh vector, constructor iterator, is the function that the compiler helps us generate, which is to call the constructor for every object in the array.   Then we'll look at the array form of delete [] what the hell is going on behind it? Focus on the top!PurpleThe code:Newtest!wmain: ....01181060 837efc00 cmp dword ptr [esi-4],0//Determine whether the number of objects is 001181064 8D46FC Lea Eax,[esi-4]//address with number of objects saved to eax01181067 740f JE newtest!wmain+0x48 (01181078)01181069 8b06 mov eax,dword ptr [esi]//Take A's virtual table address0118106b 8b5004 mov edx,dword ptr [eax+4]//second function in virtual table0118106e 6a03 Push 301181070 8BCE mov ecx,esi01181072 ffd2 call edx....you can see that it saves the object list start address to ECX, and then calls the second function in the object's virtual table, and the incoming parameter is 3, we first look at the object's virtual tables content:0:000> DPS 01182148 01182148  01181000 newtest! A::p rint [f:\test\newtest\newtest\newtest.cpp @ 11]0118214c  01181090 newtest! A:: ' vector deleting destructor '   Let's see what the function really did:0:000> u 01181090  l40newtest! A:: ' vector deleting destructor ': 01181090              push    ebx01181091 8a5c2408        mov     Bl,byte ptr [esp+8]01181095 +           &N Bsp  push    esi01181096 8bf1            mov     esi,ecx01181098 f6c302          test    bl,2//need to call destructors 0118109b 742b           &NB Sp;je      newtest! A:: ' vector deleting destructor ' +0x38 (011810C8) 0118109d 8b46fc          mov     EAX,DWO Rd PTR [esi-4]011810a0              push   &NBSP;EDI011810A1 6810101801 &nbsP    push    offset newtest! A::~a (01181010) 011810a6 8D7EFC          lea     EDI,[ESI-4]011810A9     & nbsp        push   &NBSP;EAX011810AA 6a04            push   &NBSP;4 011810AC              push    esi011810AD e87f040000Call newtest! ' eh vector destructor iterator '(01181531)011810B2 f6c301 Test bl,1//need to free memory 011810b5 7409 JE newtest! A:: ' vector deleting destructor ' +0x30 (011810C0) 011810b7 $ push EDI011810b8 e85f030000Call newtest!operator delete[] (0118141c)011810BD 83c404 add esp,4011810c0 8BC7 mov eax,edi011810c2 5f pop edi011810c3 5e pop esi011810c4 5b pop ebx011810c5 c20400 ret 4 You can see that it's internally called newtest! ' eh Vector destructor iterator, and if again trace newtest! ' eh vector destructor iterator,will look at all the objects in the array call the destructor, and finally call operator delete[] to free all memory.  the key to what we can see in arrays new[] and delete[] is that the C + + compiler holds the number of objects n 4 bytes before the start address of the array, followed by the construction and destruction of N times based on this number of values. Finally, the above analysis is limited to VS2008, in fact, in line with the C + + standard, each C + + compiler has its own different implementations. We can see that the C + + compiler has done a lot of things behind the scenes, may be inline with our functions, can also modify and produce some other functions, and this is a lot of C developers can't stand the thing, so at the kernel level, many people prefer to use C to reduce the interference behind the compiler. Finally think about it, what if our code writes like this? int _tmain (int argc, _tchar* argv[]) {A * p = new B[ten]; delete []p;return 0;}

Behind new and delete in C + +

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.