В чем разница между alloca (n) и char x [n]? - PullRequest
7 голосов
/ 10 апреля 2010

В чем разница между

void *bytes = alloca(size);

и

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

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

Ответы [ 6 ]

14 голосов
/ 10 апреля 2010

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.

6 голосов
/ 10 апреля 2010

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

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

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

5 голосов
/ 10 апреля 2010

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

0 голосов
/ 12 апреля 2010

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

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

0 голосов
/ 10 апреля 2010

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

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

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

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

0 голосов
/ 10 апреля 2010

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

...