alloca: динамическое выделение памяти в стеке |
![]() |
Добавил(а) microsin |
Известно, что локальные переменные (и параметры) функций хранятся в стеке, и поэтому автоматически уничтожаются после завершения работы этой функции. Количество выделяемой памяти в стеке для этих целей определяется в момент компиляции, и при выполнении программы фиксировано. К счастью, компилятор gcc и его библиотеки поддерживает удобную возможность динамически выделять память за счет стека с помощью alloca. [Достоинства alloca] Вот основной список причин, почему бывает предпочтительно использовать alloca вместо кучи (т. е. вместо malloc [2]): • Использование alloca очень мало занимает места под код, и этот код работает исключительно быстро. [Пример использования alloca] В качестве примера использования alloca здесь приведена функция, которая открывает файл, имя которого склеивается из двух строк, указанных в аргументах, и возвращает дескриптор файла, или вернет -1, если открыть файл не получилось: Чтобы показать это достоинства alloc, давайте предположим, что у Вас есть функция open_or_report_error наподобие open, которая возвратит дескриптор в случае успешного завершения, но не выполнит возврат в вызывающую функцию, если вызов был неудачен. Если файл не может быть открыт, то эта функция печатает сообщение об ошибке и выйдет на уровень команд вашей программы с помощью longjmp. int open2 (char *str1, char *str2, int flags, int mode) { char *name = (char *) malloc (strlen (str1) + strlen (str2) + 1); int desc; if (name == 0) fatal ("virtual memory exceeded"); stpcpy (stpcpy (name, str1), str2); desc = open (name, flags, mode); free (name); return desc; } Давайте поменяем open2 для использования этой подпрограммы open_or_report_error: int open2 (char *str1, char *str2, int flags, int mode) { char *name = (char *) alloca (strlen (str1) + strlen (str2) + 1); stpcpy (stpcpy (name, str1), str2); return open_or_report_error (name, flags, mode); } Из-за принципа работы alloca та память, которую она выделила, освободится автоматически даже когда произойдет ошибка, и для этого не нужно делать никаких специальных усилий. В отличие от предыдущего определения open2 (которое использует malloc и free), могла бы произойти утечка памяти, если изменить функцию таким же образом. Даже если Вы готовы внести больше изменений в malloc-реализацию с целью исправления ситуации, сделать это будет довольно непросто. Как можно увидеть, на основе alloca реализация намного проще. В большинстве встраиваемых систем с маломощными микроконтроллерами у alloca нет разумной альтернативы. Однако надо иметь в виду, что несмотря на все свои достоинства, использование alloca имеет и недостатки. [Недостатки alloca] Недостатки alloca в сравнении с malloc: • Если Вы попытаетесь выделить больше памяти, чем может предоставить машина, то не получите ясное сообщение об ошибке. Вместо этого скорее всего получится сигнал фатального сбоя, который происходит в случае бесконечной рекурсии. В мире PC возможно это будет сообщение о нарушении доступа к сегменту памяти. С микроконтроллерами это будет или исключение при недопустимой операции, или банальное зависание. [Ссылки] 1. Advantages of alloca site:gnu.org. |