2013-11-30 2 views
3

Это было долгое время, так как я запрограммировал в основных составителей с основными массивами, но в последнее время я увидел объявление массива, как это:переменной длины массивы VLA (статическое связывание или динамический)

int y; 
cin>>y; 
int z[y]; 

старые компиляторы время используется для указания ошибки «Размер хранилища массива не является постоянным». Затем я узнал о массивах переменных размеров в C99. Интересно, как они работают внутри страны. Это делает массив динамическим? Является ли эта память распределенной в куче? Эта привязка все еще выполняется статически? Если да, то как.

+3

C++ не имеет VLA, извините. Единственный способ, которым вы написали на работу, - использовать нестандартное расширение компилятора. – ScarletAmaranth

+0

Я не знаю, что я делаю неправильно. Я использую компилятор Orwell Dev C++, и мой код также находится в файле .cpp. Я получаю точечный компилятор, который позволяет это сделать. – Hina

+0

, но все же как привязка к работе VLA, даже в C – Hina

ответ

2

Это делает массив динамическим?

Это зависит от того, как вы определяете «динамический». VLA, конечно, не может расти или сокращаться или, другими словами, изменять свой размер после его создания. Это динамично, хотя в некотором смысле его длина неизвестна во время компиляции.

Является ли эта память выделенной в куче?

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

Ближайший родственник VLA является alloca() функцией, которая в значительной степени можно считать тот же эффект, по крайней мере, в С. Предполагая, что компилятор использует VLA таким же образом alloca() реализован, вы можете думать об этих двух массивах как технически то же самое в C:

int *a = alloca(sizeof(int) * N); 
int b[N]; 

VLA обладает, однако, более компактным и удобным синтаксисом. Но самое главное, VLA по своей природе имеет автоматическую продолжительность хранения и дает компилятору больше свободы решать, следует ли уничтожать/освобождать массив после выхода из области, где он был объявлен, или после возврата из функции.

Это становится очень важным в таких языках, как C++, где компилятор реализует RAII idiom и должен гарантировать уничтожение объектов с автоматическим временем хранения при выходе из их области.

Обратите внимание, однако, что VLA в настоящее время не является частью языка C++ и реализуется компилятором как нестандартное расширение. Но это expected to become standard in C++14.

1

Краткий ответ: он резервирует место в стеке, увеличивая указатель стека.

3

Variable Length Array (VLA) с являются особенностью С99 но несколько Составители включая gcc поддерживает VLA as an extension за пределами C99 и оба поддерживают gcc и clangмассивы переменной длины в С ++ как расширение даже если это на самом деле C99.

В обоих gcc и clang здания с использованием -pedantic флаг будет производить предупреждение похожее на следующее в C:

warning: variable length arrays are a C99 feature [-Wvla-extension] 

и что-то похожее на это в C++:

warning: ISO C++ forbids variable length array ‘z’ [-Wvla] 

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

Мы также можем видеть из C99 draft standard, что Власа просто еще одна вариация объявления массива из раздела 6.7.5.2массива declarators пункта говорит (курсив мой):

, если размера нет, тип массива является неполным. Если размер равен * вместо выражения, тип массива представляет собой массив переменных длины неопределенного размера, который может использоваться только в объявлениях с помощью области прототипа функции; 124) такие массивы, тем не менее, являются полными типами. Если размер представляет собой целочисленное константное выражение, а тип элемента имеет известный постоянный размер, тип массива не является массивом переменной длины; , в противном случае тип массива представляет собой тип массива переменной длины.

мы видим из пункта , что ее размер не меняется в течение его жизни:

[...] Размер каждого экземпляра типа переменной длины массива не изменяется в течение его жизни. [...]

Хотя большая разница с VLAS и других переменных является то, что SizeOf является оценивали для VLAS в то время как в противном случае оно вычисляется во время компиляции, из раздела 6.5.3.4Оператор SizeOf пункта :

[...] Если тип операнда является массивом переменной длины , операнд оценивается; в противном случае операнд не оценивается, а результат является целочисленной константой.

+0

VLA - это также APL, Algol, COBOL и почти C++ функция ... :) –

+0

@ VladLazarenko wrt to * C * и * C++ * это функция C99, но поскольку статья в Википедии, которую я связал, упоминает ее не является исключением. –

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