Каково различие между alloca (n) и символом x [n]?

Между чем различие

void *bytes = alloca(size);

и

char bytes[size];  //Or to be more precise, char x[size]; void *bytes = x;

... где размер является переменной, значение которой неизвестно во время компиляции.

7
задан Shog9 15 August 2010 в 19:24
поделиться

6 ответов

alloca () не освобождает память до завершения текущей функции, в то время как массив переменной длины освобождает память по завершении текущего блока.

Другими словами:

void foo()
{
    size_t size = 42;
    if (size) {
        void *bytes1 = alloca(size);
        char bytes2[size];
    } // bytes2 is deallocated here
}; //bytes1 is deallocated here

alloca () может поддерживаться (в некотором роде) любым компилятором C89, в то время как массив переменной длины требует компилятора C99.

15
ответ дан 6 December 2019 в 06:49
поделиться

Из документации GNU :

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

Кроме того, alloca не является стандартом Функция C, поэтому поддержка не гарантируется во всех компиляторах. Массивы переменной длины являются частью стандарта C99, поэтому любой компилятор, поддерживающий C99, должен его реализовать.

6
ответ дан 6 December 2019 в 06:49
поделиться

Помимо упомянутого Билли пункта, alloca нестандартен (его даже нет в C99).

5
ответ дан 6 December 2019 в 06:49
поделиться

Помимо уже обсуждавшихся моментов, когда именно освобождается пространство и поддерживается ли вообще конструкция, существует также следующее:

  • В случае alloca , bytes имеет тип указателя.
  • В случае [] байтов имеет тип массива.

Наиболее заметная разница в том, что такое sizeof (bytes) ; для указателя это размер указателя ( sizeof (void *) ), тогда как для массива это размер выделенного пространства ( sizeof (char) * size , который = size для этого случая, поскольку sizeof (char) = 1).

(Кроме того, в вашем примере типы элементов разные; чтобы быть одинаковыми, первый должен быть изменен на char * bytes = alloca (size) .)

{{1} }
0
ответ дан 6 December 2019 в 06:49
поделиться

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

0
ответ дан 6 December 2019 в 06:49
поделиться

Самая большая разница в том, что alloca делает не вызывайте конструкторы или деструкторы, когда вы используете память как переменные класса.

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

0
ответ дан 6 December 2019 в 06:49
поделиться
Другие вопросы по тегам:

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