Разрешен размер массива во время выполнения без динамического распределения?
Я использую С++ в течение нескольких лет, и сегодня я видел некоторый код, но как это может быть совершенно законным?
int main(int argc, char **argv)
{
size_t size;
cin >> size;
int array[size];
for(size_t i = 0; i < size; i++)
{
array[i] = i;
cout << i << endl;
}
return 0;
}
Скомпилировано под GCC.
Как определить размер во время выполнения без new
или malloc
?
Просто, чтобы дважды проверить, у меня есть googled, и все похожие коды на мой, как утверждается, дают ошибку размера хранилища.
Даже Deitel С++ Как программировать с. 261 в рамках общей ошибки программирования 4.5:
Только константы могут использоваться для объявления размера автоматических и статических массивов.
Просветите меня.
Ответы
Ответ 1
Это действительно на C99.
Стандарт C99 поддерживает массивы с переменным размером в стеке. Вероятно, ваш компилятор также решил поддержать эту конструкцию.
Обратите внимание, что это отличается от malloc
и new
. gcc
выделяет массив в стеке, как и при использовании int array[100]
, просто корректируя указатель стека. Выделение кучи не выполняется. Это очень похоже на _alloca
.
Ответ 2
Это известно как VLA (массивы переменной длины). Он стандартный в c99, но gcc разрешает его в С++-коде как расширение. Если вы хотите, чтобы он отклонил код, попробуйте поэкспериментировать с параметрами -std=standard
, -ansi
и -pedantic
.
Ответ 3
valid только в C99. В следующий раз вы можете попробовать проверить свой код в надежном компиляторе.
Ответ 4
Действителен C99, он недействителен С++. Это одно из немногих различий между двумя языками.
Ответ 5
Вы можете динамически задать размер массива, если вы используете компилятор Dev-Cpp. Я попробовал его
и не получили никакой ошибки, но на визуальных компиляторах С++ и visual studio это невозможно.
Я думаю, причина в том, что dev-С++ присваивает положительное число неинициализированному int
и когда мы даем ему число, оно заменяется данным.
но, возможно, другие компиляторы дают null неинициализированным переменным.
Ответ 6
Этот код работает в компиляторе GNU GCC.
#include<bits/stdc++.h>
int main(int argc, char **argv)
{
size_t size;
std:: cin >> size;
int array[size];
for(size_t i = 0; i < size; i++)
{
array[i] = i;
std:: cout << i;
}
return 0;
}
Ответ 7
Недавно я столкнулся со сценарием, в котором требуется массив, выделенный стеком. (Это обертка вокруг v8, для каждого вызова метода нужен массив аргументов).
Std :: vector будет выделять кучу памяти, производительность которой неприемлема.
Вот мое решение, используйте шаблон для распределения массива дел:
template<size_t Argc>
static void call(...) {
v8::Local<v8::Value> v8Args[Argc];
// use v8Args
...
}
template<typename It>
static void callV8Function(size_t argc, It argvBegin, It argvEnd,) {
// C++ don't have dynamic stack allocation (like C99 does)
// try to avoid heap-allocation...
if (argc <= 4) {
return callV8FunctionOnStack<4>(...);
} else if (argc <= 8) {
return callV8FunctionOnStack<8>(...);
} else if (argc <= 16) {
return callV8FunctionOnStack<16>(...);
} else if (argc <= 32) {
return callV8FunctionOnStack< 32>(...);
} else {
std::vector<v8::Local<v8::Value>> v8Args(argc);
// fallback to vector
}
}
(И, конечно, я могу просто использовать массив размером 32, но это не так уж и элегантно.)
Ответ 8
Массивы переменной длины (VLAs) поддерживаются в стандарте С++ 14, который был недавно принят и ожидает публикации.