Dynamic allocation of memory

Lets consider following two codes

First:

for (int i=0;i<10000000;i++)
{
    char* tab = new char[500];
    delete[] tab;
}

Second:

for (int i=0;i<10000000;i++)
{
    char tab[500];
}

The peak memory usage is almost the same, but the second code runs about 20 times faster than the first one.

Question
Is it because in first code array is stored on heap, and in the second one array is stored on stack?


Is it because in first code array is stored on heap, and in the second one array is stored on stack?

Yes, Stack allocation is much faster as all the second code sample is doing is moving (adding/subtracting) the stack pointer rather than manipulating the heap.

If you want to know more, these two questions cover the subject

  • C++ Which is faster: Stack allocation or Heap allocation
  • What and where are the stack and heap

  • Yes. allocating arrays on the heap is much, much slower than creating them automatically. The former may involve a system call, and will always involve manipulating heap structures, whereas the latter simply adjusts the stack pointer.


    Just to confirm 2 previous answers, when profiling such code (in Visual Studio), and looking at assembly code, first one calls operator new and second does not which means its allocated automatically on stack.

    Here's how it looks

    int _tmain(int argc, _TCHAR* argv[])
    {
    00401000  push        ebp  
    00401001  mov         ebp,esp 
    00401003  sub         esp,304h 
    00401009  push        ebx  
    0040100A  push        esi  
    0040100B  push        edi  
    0040100C  lea         edi,[ebp-304h] 
    00401012  mov         ecx,0C1h 
    00401017  mov         eax,0CCCCCCCCh 
    0040101C  rep stos    dword ptr es:[edi] 
        for (int i=0;i<10000;i++)
    0040101E  mov         dword ptr [i],0 
    00401025  jmp         wmain+30h (401030h) 
    00401027  mov         eax,dword ptr [i] 
    0040102A  add         eax,1 
    0040102D  mov         dword ptr [i],eax 
    00401030  cmp         dword ptr [i],2710h 
    00401037  jge         wmain+6Fh (40106Fh) 
        {
            char* tab = new char[500];
    00401039  push        1F4h 
    0040103E  call        operator new[] (4010F0h) 
    00401043  add         esp,4 
    00401046  mov         dword ptr [ebp-300h],eax 
    0040104C  mov         eax,dword ptr [ebp-300h] 
    00401052  mov         dword ptr [tab],eax 
            delete[] tab;
    00401055  mov         eax,dword ptr [tab] 
    00401058  mov         dword ptr [ebp-2F4h],eax 
    0040105E  mov         ecx,dword ptr [ebp-2F4h] 
    00401064  push        ecx  
    00401065  call        operator delete[] (401104h) 
    0040106A  add         esp,4 
        }
    0040106D  jmp         wmain+27h (401027h) 
    
        for (int i=0;i<10000;i++)
    0040106F  mov         dword ptr [i],0 
    00401076  jmp         wmain+81h (401081h) 
    00401078  mov         eax,dword ptr [i] 
    0040107B  add         eax,1 
    0040107E  mov         dword ptr [i],eax 
    00401081  cmp         dword ptr [i],2710h 
    00401088  jge         wmain+8Ch (40108Ch) 
        {
            char tab[500];
        }
    0040108A  jmp         wmain+78h (401078h) 
    
        return 0;
    0040108C  xor         eax,eax 
    }
    
    链接地址: http://www.djcxy.com/p/79176.html

    上一篇: 何时调用C ++析构函数?

    下一篇: 内存的动态分配