Что является разумным показательным размером, когда лучше перейти от стека к куче?

Является

WCHAR bitmapPathBuffer[512]

ok для распределения стека? или лучше использовать кучу для такого размера? Что является разумным показательным размером, когда лучше перейти от стека к куче... все говорят, что "зависит", но наши мозги нуждаются в некоторых ограничениях для ориентиров.

Ответ 1

Возможно, вы захотите проверить размер стека по умолчанию в системном стандарте и подумать о том, какое использование вашего приложения сделает из рекурсии, чтобы достичь некоторого разумного порога.

В любом случае, для обычных настольных ПК я бы сказал, что ~ 100 кб было бы разумно разместить в стеке для функции, которая не будет вызываться рекурсивно без каких-либо необычных соображений (мне пришлось пересмотреть это вниз, увидев, как ограничительная Windows была ниже), Вы можете быть на уровне порядка более или менее на определенных системах, но вокруг этого момента вы начнете заботиться о проверке своих системных ограничений.

Если вы обнаружите, что делаете это во многих функциях, вам лучше подумать о том, можно ли вызвать эти функции друг от друга или просто распределить динамически (желательно неявно с помощью vector, string и т.д..) и не беспокойтесь об этом.

Рекомендация 100kb основана на эти значения размера стека по умолчанию, вырванные из 'net:

platform    default size    # bits  # digits
    ===============================================================
SunOS/Solaris   8172K bytes <=39875 <=12003 (Shared Version)
Linux       8172K bytes <=62407 <=18786
Windows     1024K bytes <=10581 <=3185  (Release Version)
cygwin      2048K bytes <=3630  <=1092

Ответ 2

Как говорили другие, ответ на этот вопрос зависит от системы, в которой вы работаете. Чтобы прийти к разумному ответу, вам нужно знать:

  • Размер стека по умолчанию. Это может отличаться для потоков, отличных от основного потока (!), Или если вы используете закрытие или стороннюю библиотеку потоков или сопрограммы.
  • Динамический размер системного стека. В некоторых системах стек может автоматически вырасти до точки.
  • На некоторых платформах (например, на системах ARM или PowerPC) есть "красная зона". Если вы используете функцию листа (тот, который не вызывает других функций), если ваше использование стека меньше размера красной зоны, компилятор может генерировать более эффективный код.

Как правило, я согласен с другими респондентами в том, что в настольной системе 16-64 КБ или около того является разумным пределом, но даже это зависит от таких вещей, как глубина рекурсии. Конечно, большие фреймы стека являются запахом кода и должны быть исследованы, чтобы убедиться, что они необходимы.

В частности, стоит подумать о длинах любых буферов, выделенных в стеке... они действительно достаточно велики для любого мыслимого ввода? И проверяете ли вы это во время выполнения, чтобы избежать переполнения? например В вашем примере вы уверены, что bitmapPathBuffer не длиннее 512 WCHAR по длине? Если вы точно не знаете максимальную длину, куча может быть лучше. Даже тогда, если это состязательная среда, вы можете уделить ей большую верхнюю границу, чтобы избежать атак, связанных с исчерпанием памяти.

Ответ 3

Ответ действительно "зависит".

Если у вас много таких переменных, или если вы выполняете относительно большие распределения стека в своей функции и в функциях, которые она вызывает, то возможно, что у вас будет переполнение стека.

Типичный размер стека по умолчанию для исполняемого файла Win32 - 1 МБ. Если вы выделите более того, у вас возникнут проблемы и вы должны изменить самые большие распределения, чтобы быть в куче.

Я бы выполнил простое правило - если ваши распределения больше, чем говорят 16 - 64 КБ, а затем выделяйте кучу. В противном случае должно быть нормально выделять стек.

Ответ 4

Современные компиляторы при нормальных обстоятельствах используют размер стека около 1 мегабайта. Таким образом, 1 KB не является проблемой для простой программы.

Если программа очень сложна, другие функции в цепочке вызовов также используют большие части стека, ваша текущая функция очень глубока в стеке вызовов и т.д., тогда вам лучше избегать больших автоматических переменных.

Если вы используете рекурсию, вам следует внимательно изучить, насколько она может быть глубокой.

Если вы напишете функцию, которая будет использоваться в других проектах или другими людьми, тогда вы никогда не узнаете, можно ли ее вызывать в рекурсивной функции или глубоко в стеке. Поэтому обычно рекомендуется избегать больших автоматических переменных в этом случае.

Ответ 5

Нет жесткого ограничения, но вы можете подумать о том, что происходит, если распределение не выполняется. Если выделение локального переменная не работает, ваша программа вылетает из строя; если распределение динамического переменная не работает, вы получаете (или должны получить) исключение. Для этого разум, я склонен использовать динамическое распределение (в форме std::vector) для чего угодно около 1K. Дело в том, что std::vector проверяет границы (по крайней мере, с реализации, которые я использую) при компиляции без оптимизации плюс плюс.