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