Множество интересных ответов на этот "старый" вопрос, даже некоторые относительно новые ответы, но я не нашел ни одного, который бы упоминал об этом ....
При правильном и осторожном использовании alloca()
(возможно, для всего приложения) для обработки небольших распределений переменной длины
(или C99 VLA, где доступно) может привести к снижению общего стека
рост по сравнению с другой эквивалентной реализацией с использованием негабаритных
локальные массивы фиксированной длины. Так что alloca()
может быть хорошо для вашего стека , если вы используете его осторожно.
Я нашел эту цитату в .... Хорошо, я сделал эту цитату. Но на самом деле, подумай об этом ....
@ j_random_hacker очень прав в своих комментариях к другим ответам: отказ от использования alloca()
в пользу увеличенных локальных массивов не делает вашу программу более безопасной от переполнения стека (если ваш компилятор не достаточно стар, чтобы разрешить встраивание функций, которые используйте alloca()
, в этом случае вам следует обновить или, если вы не используете alloca()
внутри циклов, и в этом случае вы не должны ... не использовать alloca()
внутри циклов).
Я работал на настольных / серверных средах и встроенных системах. Многие встраиваемые системы вообще не используют кучу (они даже не ссылаются на ее поддержку) по причинам, которые включают в себя восприятие, что динамически выделяемая память является злом из-за риска утечек памяти в приложении, которое никогда не будет когда-либо перезагружается годами или более разумным обоснованием того, что динамическая память опасна, поскольку невозможно точно знать, что приложение никогда не фрагментирует свою кучу до точки ложного исчерпания памяти. Таким образом, у встроенных программистов остается несколько альтернатив.
alloca()
(или VLA) может быть просто подходящим инструментом для работы.
Я снова и снова видел, как программист делает выделенный стеком буфер, «достаточно большой, чтобы обрабатывать любые возможные случаи». В глубоко вложенном дереве вызовов повторное использование этого (анти -?) Шаблона приводит к чрезмерному использованию стека. (Представьте себе дерево вызовов глубиной 20 уровней, где на каждом уровне по разным причинам функция слепо перераспределяет буфер в 1024 байта «просто для безопасности», когда обычно она использует только 16 или менее из них, и только в очень в редких случаях может использоваться больше.) Альтернатива - использовать alloca()
или VLA и выделять только столько стекового пространства, сколько требуется вашей функции, чтобы избежать ненужной нагрузки на стек. Надеемся, что когда одна функция в дереве вызовов нуждается в распределении, превышающем нормальное, другие в дереве вызова все еще используют свои обычные небольшие выделения, и общее использование стека приложения значительно меньше, чем если бы каждая функция слепо перераспределяла локальный буфер .
Но если вы решите использовать alloca()
...
Судя по другим ответам на этой странице, кажется, что VLA должны быть безопасными (они не объединяют распределения стека при вызове из цикла), но если вы используете alloca()
, будьте осторожны, чтобы не использовать его внутри цикла и сделайте уверенным , что ваша функция не может быть встроена, если есть вероятность, что она может быть вызвана в цикле другой функции.