2010-04-10 4 views
7

В чем разница междуВ чем разница между alloca (n) и char x [n]?

void *bytes = alloca(size); 

и

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

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

+1

Ответ критически зависит от того, является ли 'size' константой времени компиляции. Это? – AnT

+0

нет, размер есть, для всех целей и целей, аргумент функции –

+0

Это не имеет значения. Apple по умолчанию использует '--std = gnu99', который поддерживает оба. 'alloca()' является расширением GNU, а массив переменной длины - совместимой с C99 функцией. –

ответ

13

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 компилятор.

+2

@Billy: память, выделенная символом char bytes [size], не гарантируется физически исправлена ​​в конце текущего блока; однако доступ после текущего блока больше невозможен. – Vlad

+0

Какой компилятор это делает? –

+2

@ Vlad: Технически стандарт C упоминает очень мало о том, где вещи действительно должны быть физически сохранены, чтобы избежать любой возможной зависимости от конкретной архитектуры. Однако, даже если что-то явно не указано в стандарте, неявное значение в стандарте приводит к тому, что 99,9% компиляторов реализуют его таким образом. –

0

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

+3

Не в C99. (15chars) –

+0

@Billy: Действительно. – Vlad

+0

Возможно, но, скорее всего, OP относится к массивам переменной длины, являющимся частью стандарта C99. – rjh

6

От GNU documentation:

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

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

+0

Даже если это не поддерживается вашим компилятором, обычно доступны общедоступные версии 'alloca'. –

+0

Обратите внимание, что alloca() указан в POSIX.1-2001 – martinkunev

5

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

0

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

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

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

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

0

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

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

Смежные вопросы