2013-05-21 3 views
15

Существует два способа выделения памяти массиву, размер которого неизвестен в начале. Наиболее распространенным способом является использование malloc как этотmalloced array VS. variable-length-array

int * array; 
... // when we know the size 
array = malloc(size*sizeof(int)); 

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

... // when we know the size 
int array[size]; 

Они абсолютно то же самое?

+4

Во-вторых, даже в C99, не всегда справедливо. В соответствии с C99 §6.10.8.3 «Макросы условных функций» реализация может определять ** __ STDC_NO_VLA __ ** и *** no *** реализовать массивы переменной длины и * все еще соответствовать стандарту. * – WhozCraig

+2

** Это не дублированный вопрос **! Ни один из упомянутых вопросов не содержит подробностей о различиях. – Jens

+2

@WhozCraig AFAIK, это вещь 2011 года. Нет такого раздела в том, что у меня есть, чтобы быть копией стандарта C99. –

ответ

26

Нет, они не совсем одинаковы. В то время как позволяют хранить такое же количество и тип объектов, иметь в виду, что:

  • Вы можете free() malloced массив, но вы не можете free() массив переменной длины (хотя он выходит из области видимости и прекращается чтобы существовать после того, как останется закрытый блок). На техническом жаргоне они имеют различную продолжительность хранения : выделено для malloc по сравнению с automatic для массивов переменной длины.
  • Несмотря на то С не имеет концепции стека, многие реализации выделяют переменную длину массив из стека, в то время как malloc выделяет из кучи . Это проблема в системах с ограниченным стеком, например. многие встроенные операционные системы, где размер стека составляет порядка kB, а куча намного больше.
  • Также легче проверить неудавшееся распределение с помощью malloc, чем с массивом переменной длины.
  • Память malloced может быть изменена в размере с помощью realloc(), в то время как VLA не может (точнее, только путем повторного выполнения блока с другим размером массива, который теряет предыдущее содержимое).
  • Проведенная реализация C89 поддерживает только malloc().
  • Проведенная реализация C11 может не поддерживать массивы переменной длины (тогда она должна определять __STDC_NO_VLA__ как целое число 1 согласно C11 6.10.8.3).
  • Все остальное я пропустил :-)
+2

VLA выходит из области видимости (перестает быть видимой) в конце закрывающего блока, поскольку имеет область действия блока.Он перестает существовать в конце блока, поскольку он имеет автоматическую продолжительность хранения. Две разные вещи. –

+0

@ KeithThompson Спасибо за терминологический намек; Я отредактировал ответ, чтобы быть более точным. – Jens

+2

@ KeithThompson: Если быть точным, идентификатор массива выходит за пределы области действия в конце закрывающих блоков. Области - это свойства идентификаторов (имен), а не объектов. Объект может быть доступен вне области его идентификатора, так как когда его адрес передается другой подпрограмме. –