Вдохновлен этим вопросом .
Видимо в следующем коде:
#include <Windows.h>
int _tmain(int argc, _TCHAR* argv[])
{
if( GetTickCount() > 1 ) {
char buffer[500 * 1024];
SecureZeroMemory( buffer, sizeof( buffer ) );
} else {
char buffer[700 * 1024];
SecureZeroMemory( buffer, sizeof( buffer ) );
}
return 0;
}
скомпилировано с размером стека по умолчанию (1 мегабайт) с помощью Visual C ++ 10 с оптимизациейв (/ O2) переполнение стека происходит из-за того, что программа пытается выделить 1200 килобайт в стеке.
Приведенный выше код, конечно, немного преувеличен, чтобы показать проблему - использует много стека довольно тупым способом.Тем не менее, в реальных сценариях размер стека может быть меньше (например, 256 килобайт), и может быть больше веток с более мелкими объектами, которые приводят к общему размеру выделения, достаточному для переполнения стека.
Это не имеет смысла.В худшем случае это будет 700 килобайт - это будет кодовая дорожка, которая строит набор локальных переменных с наибольшим общим размером.Обнаружение этого пути во время компиляции не должно быть проблемой.
Таким образом, компилятор создает программу, которая пытается выделить даже больше памяти, чем в худшем случае.Согласно этот ответ LLVM делает то же самое.
Это может быть недостатком в компиляторе или может быть какая-то реальная причина сделать это таким образом.Я имею в виду, может быть, я просто не понимаю что-то в дизайне компиляторов, которое объясняет, почему такое размещение необходимо.
Почему компилятор хотел бы, чтобы программа выделяла больше памяти, чем требуется коду в худшем случае?