Позволяет рассматривают следующие два кода
Во-первых:
for (int i=0;i<10000000;i++)
{
char* tab = new char[500];
delete[] tab;
}
Во-вторых:
for (int i=0;i<10000000;i++)
{
char tab[500];
}
Пиковое использование памяти является почти тем же, но второй код работает приблизительно в 20 раз быстрее, чем первый.
Вопрос
Это, потому что в первом коде массив хранится на "куче", и во втором массив хранится на стеке?
Это потому, что в первом коде массив хранится в куче, а во втором - в стеке?
Да, выделение стека происходит гораздо быстрее, поскольку все, что делает второй пример кода, это перемещает (добавляет/вычитает) указатель стека, а не манипулирует кучей.
Если вы хотите узнать больше, эти два вопроса охватывают тему
Просто чтобы подтвердить 2 предыдущих ответа, при профилировании такого кода (в Visual Studio) и просмотре кода сборки первый вызывает оператор new, а второй - нет, что означает, что он автоматически выделяется в стеке.
Вот как это выглядит
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
}
Вы пробовали запустить его с включенной оптимизацией? Я был бы очень удивлен, если бы после включения оптимизатора вообще была какая-либо разница. Фактически, я ожидал, что оптимизатор полностью удалит цикл в обоих случаях.
Да. Выделение массивов на куче намного, намного медленнее, чем их автоматическое создание. Первое может включать системный вызов и всегда будет включать манипуляции со структурами кучи, тогда как второе просто корректирует указатель стека.