Действительно ли alloca абсолютно заменим?

Я считал довольно много мест это alloca является устаревшим и не должен использоваться, и Массивы Переменной длины должны использоваться вместо этого.

Мой вопрос - это: alloca абсолютно заменимый массивами переменной длины?

В моем конкретном экземпляре у меня есть что-то, что похоже на это:

typedef struct { 
  int *value; 
  size_t size; 
  } some_type;

void SomeExternalFunction(some_type);

...

void foo(){
  //What I thought to do
  some_type bar;
  bar.value=alloca(sizeof(int)*10);
  SomeExternalFunction(bar);

  //what should be done without alloca
  some_type fizz;
  int tmp[10];
  fizz.value=tmp;
  SoemExternalFunction(fizz);
}

Я пропускаю что-то, или действительно ли это - фактическое хорошее использование alloca? Также предположите для этого примера, что по некоторым причинам я хочу, чтобы значение было выделено на стеке

8
задан Earlz 15 August 2010 в 19:12
поделиться

2 ответа

Существует важное различие между VLA и alloca: функция memory alloca () возвращает значение , пока сохраняется текущая функция . Время жизни памяти, занимаемой VLA, является действительным, пока идентификатор VLA остается в области видимости . Вы можете, например, выделить память a () в цикле и использовать память вне цикла, VLA исчезнет, ​​потому что идентификатор выходит за пределы области действия, когда цикл завершается. Это означает, что вы можете сделать это с помощью alloca () и достаточно места в стеке:

typedef struct node { int data; struct node *next; };
void fun()
{
 struct node *n=0;
 int d;
 /* Now we are building a single-linked list on the stack! */
 while(d=get_something()) {
  struct node *x=alloca(sizeof(*x));
  x->next=n; 
  x->data=d;
  n=x;
 }
 do_something_with(n);
} // and the whole thing is deleted here..

Вы не можете сделать это с помощью VLA.

22
ответ дан 5 December 2019 в 07:33
поделиться

alloca полностью заменяется malloc и free. Это немного больше работы, но если вы не очень осторожны, это необходимо. Почти весь код, использующий alloca или C99 vla's, уязвим для атак переполнения стека, и во многих реализациях они могут привести к повышению привилегий. Нет никакого переносимого способа узнать, насколько велик стек или сколько места в стеке осталось (или сколько накладных расходов сверх запрашиваемого размера может потребоваться для внутреннего использования компилятором или дальнейших вызовов функций), поэтому единственное разумное, что вы можете сделать для обеспечения безопасности vla's/alloca - это наложить очень небольшие искусственные ограничения на размер поддерживаемых данных (например, несколько кб). С таким же успехом вы могли бы просто использовать обычные автоматические объекты непеременной длины...

0
ответ дан 5 December 2019 в 07:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: