В каких случаях полезно использовать alloca ()? - PullRequest
3 голосов
/ 10 августа 2010

Зачем вам когда-либо хотеть использовать alloca (), когда вы всегда можете выделить буфер фиксированного размера в стеке, достаточно большом для всех применений?Это не риторический вопрос ...

Ответы [ 6 ]

2 голосов
/ 10 августа 2010

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

0 голосов
/ 22 ноября 2016

Использование alloca() может быть разумным, если вы не можете использовать malloc() (или new в C ++, или другом распределителе памяти) надежно или вообще, но вы можете предположить, что есть больше место в вашем стеке - то есть, когда вы больше ничего не можете сделать.

Например, в glibc s segfault.c мы имеем:

 /* This function is called when a segmentation fault is caught.  The system
    is in an unstable state now.  This means especially that malloc() might
    not work anymore.  */
static void
catch_segfault (int signal, SIGCONTEXT ctx)
{
    void **arr;

    /* ... */

    /* Get the backtrace.  */
    arr = alloca (256 * sizeof (void *));

    /* ... */
}
0 голосов
/ 11 августа 2010

Функция alloca() практически никогда не нужна;в целях выделения памяти вы можете использовать malloc() / free() в C (или одну из совокупности возможностей в C ++) и достичь почти такого же практического эффекта.Это имеет преимущество в том, что лучше справляется с меньшими размерами стека.

Однако Я видел [1] одно законное (если хак!) Его использование: для обнаруженияпотенциальное переполнение стека в Windows;если выделение (того количества отстойного пространства, к которому вы хотели получить доступ) не удалось, вы вышли, но у вас было достаточно места для изящного восстановления.Он был обёрнут в __try / __except, чтобы не вылетать, и требовал дополнительных трюков на ассемблере, чтобы избежать проблем, связанных с gcc.Как я уже сказал, взломать.Но умное, единственное допустимое использование для alloca(), которое я когда-либо видел.

Но не делайте этого.Лучше написать код, чтобы не нуждаться в таких играх.


[1] Это было в Tcl 8.4 (и, возможно, в более ранних версиях Tcl).Это было удалено в более поздних версиях.Более поздние версии удалили это, потому что это было привередливым, очень хитрым и глубоко тревожащим.8.6 использует реализацию стека механизма исполнения вместо такого рода фанки.

0 голосов
/ 10 августа 2010

В каких случаях полезно использовать alloca ()?

Единственный раз, когда я видел использование alloca, был в Open Dynamics Engine.AFAIK они выделяли ОГРОМНЫЕ матрицы с помощью этого (таким образом, скомпилированная программа могла требовать стека в 100 МБ), которые автоматически освобождались при возврате функции (для меня это выглядит как подделка smartpointer).Это было довольно давно.

Хотя это было, вероятно, намного быстрее, чем new / malloc, я все же думаю, что это была плохая идея.Вместо вежливого завершения работы ОЗУ программа может аварийно завершить работу с переполнением стека (т.е. вводить в заблуждение), когда сцена становится слишком сложной для обработки.Неприличное поведение, IMO, особенно для физического движка, где вы можете легко ожидать, что кто-то бросит несколько тысяч кирпичей в сцену и увидит, что происходит, когда все они сталкиваются одновременно.Кроме того, вы должны были установить размер стека вручную - то есть в системе с большим объемом ОЗУ программа все равно будет ограничена размером стека.

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

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

0 голосов
/ 10 августа 2010

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

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

0 голосов
/ 10 августа 2010

Никогда - это не является частью C ++ и бесполезно в C. Однако вы не можете выделить «статический буфер в стеке» - статические буферы размещаются во время компиляции, а не в стеке.

Суть alloca (), конечно, в том, что он не имеет фиксированного размера, он находится в стеке и что он автоматически освобождается при выходе из функции.И в C ++, и в C есть лучшие механизмы для этого.

...