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