Размер массива C++, зависящий от параметра функции, вызывает ошибки компиляции

18
задан Peter Mortensen 6 January 2010 в 22:08
поделиться

7 ответов

Что Вы нашли это одним из расширений компилятора Гну языка C++. В этом случае Visual C++ абсолютно корректен. Массивы в C++ должны быть определены с размером, который является константным выражением времени компиляции.

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

в C++ существует два решения. Первое должно использовать станд.:: вектор, второе должно только использовать оператор new []:

char *a = new char [n];

, В то время как я писал свой ответ, другой отправил предложение для использования _alloca. Я настоятельно рекомендовал бы против этого. Вы просто обменивались бы одним нестандартным, непортативным методом для другого столь же определенного для компилятора.

28
ответ дан 30 November 2019 в 06:29
поделиться

Ваш метод выделения от стека является g ++ расширение. Чтобы сделать эквивалент под MSVC, необходимо использовать _alloca:

char *a = (char *)_alloca(n);
10
ответ дан 30 November 2019 в 06:29
поделиться

Вы используете что-то, что не является стандартом. На самом деле это - стандартный C, но не C++. Насколько странный это!

Объяснение немного больше, время выполнения измеренные массивы стека не являются частью C++, но являются частью C99, последнего стандарта для C. ThatВґs, почему некоторые компиляторы получат его, в то время как другие не будут. Я рекомендовал бы рефрен от использования его, для предотвращения проблем совместимости компилятора.

альтернативная реализация функциональности использовала бы новый и удалять, как отправлено strager.

5
ответ дан 30 November 2019 в 06:29
поделиться

Можно использовать новый/удаляющий для выделения/свободной памяти на "куче". Это медленнее и возможно более подвержено ошибкам, чем использование символа [n], но это еще не часть стандарта C++, печально.

Вы можете, использовал ограниченный по объему класс массива повышения для надежного метода исключения для использования нового []. удалите [], автоматически назван на , когда это выходит из объема.

void f(int n) {
    boost::scoped_array<char> a(new char[n]);

    /* Code here. */
}

можно также использовать станд.:: вектор и резерв () некоторые байты:

void f(int n) {
    std::vector<char> a;
    a.resize(n);

    /* Code here. */
}

, Если Вы делаете , хотят использовать символ [n], скомпилировать, поскольку C99 кодируют вместо кода C++.

, Если абсолютно необходимо выделить данные по стеку по некоторым причинам, используйте _alloca или _malloca / _ freea, которые являются расширениями, обеспеченными MSVC, освобождает и такой.

2
ответ дан 30 November 2019 в 06:29
поделиться

Обычно в C (за исключением компиляторов C99, поскольку другие указали) и C++, если Вы хотите выделить память на стеке, размер того, что Вы хотите выделить, должен быть известен во время компиляции. Локальные переменные выделяются на стеке, таким образом, массив, длина которого зависит от параметра функции во время выполнения, нарушает это правило. Klein корректен, чтобы указать, что использование 'нового' оператора является одним способом решить эту проблему:


char *a = new char [n];

все еще, который локальная переменная выделила на стеке, но вместо того, чтобы быть целым массивом (который имеет переменную длину), это - просто указатель на массив (который всегда является тем же размером, и таким образом известный во время компиляции). Массив выделяется на "куче", которая обычно играет дубликат стека - стек для вещей с размером, известным во время компиляции, и "куча" для вещей с размером, не известным во время компиляции.

1
ответ дан 30 November 2019 в 06:29
поделиться

Массив переменной длины был введен в C99. Он поддерживается в gcc, но не в msvc. По словам человека из команды MSVC, Microsoft не планирует поддерживать эту функцию в своем компиляторе c / C ++. Он предложил использовать в таких случаях std :: vector.

Обратите внимание, что C99 не требует выделения массива в стеке. Компилятор может разместить его в куче. Однако gcc выделяет массив в стеке.

2
ответ дан 30 November 2019 в 06:29
поделиться

Целесообразно ли использовать вектор<> , а не массив? Или, так как вы заменяете char *, a std::string? Они хорошо работают с размерами времени исполнения, хотя могут быть и другие причины не использовать их.

1
ответ дан 30 November 2019 в 06:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: