myArray [N] где N = 1 000 000 возвращает ошибку, а myArray [1 000 000] - нет - PullRequest
0 голосов
/ 08 ноября 2018

Расширение файла: .cpp

У меня есть следующий код:

int main() {
    int N; cin >> N;
    int myArray[N];
    return 0;
}

Я получаю сообщение об ошибке при попытке запустить эту программу, если я введу N как 1,000,000.Однако, когда я устанавливаю myArray[N] в myArray[1000000], это не так.Почему это происходит?

Ответы [ 5 ]

0 голосов
/ 08 ноября 2018

Это происходит потому, что размер статических массивов должен быть известен во время компиляции .

Настоятельно рекомендуется использовать std :: vector вместо массивов для большей гибкости и безопасности (это всегда ответ: используйте vector, если это возможно). Вы можете использовать std :: vector :: reserve , чтобы запросить емкость как минимум той длины, которую вы хотите. Используйте std :: vector ::acity , чтобы увидеть текущую емкость.

#include <iostream>
#include <vector>

int main () {
  std::vector<int> ivec;
  ivec.reserve(100);
  std::cout << ivec.capacity() << std::endl;
  return 0;
}

Выход:

100

Только если у вас есть очень хорошая причина для предпочтения массивов над векторами, вы можете динамически распределять массив. Использование std :: shared_ptr делает этот процесс намного более безопасным и удобным. Вот как это делается так, как вы хотите:

#include <iostream>
#include <memory>

int main () {
  int N;
  std::cin >> N;
  std::shared_ptr<int> arr_ptr (new int[N],  std::default_delete<int[]>());
  for (int i = 0; i != N; ++i) {
    arr_ptr.get()[i] = i * 2;
  }

  for (int i = 0; i != N; ++i) {
    std::cout << arr_ptr.get()[i] << std::endl;
  }
  return 0;
} 

Введите:

10

Выход:

0
2
4
6
8
10
12
14
16
18
0 голосов
/ 08 ноября 2018

Прежде всего VLA (массивы переменной длины) - это расширение C ++. Компиляторы поддерживают это, так как обычно они поддерживают также C, который имеет эту функциональность в стандарте.

Вторая проблема - этот массив размещается в стеке. Стек имеет очень ограниченный размер. Таким образом, когда ваше N имеет очень большое значение, приложение может аварийно завершить работу, поскольку стек переполнится.

В этом случае вы должны использовать std::vector, который будет распределять данные в куче.

Вопрос, почему массив со статическим размером массива не падает? Там может быть пара причин.

  1. Компилятор замечает, что массив не используется, и на основе правила «Как будто» массив удаляется.
  2. Компилятор знает размер массива во время компиляции, поэтому требуемый размер стека известен. Эта информация может быть передана компоновщику, и приложение создается с большим размером стека, чем значение по умолчанию (в случае одного приложения suorce-кода это может быть возможно). Отказ от ответственности: это мое предположение, я не проверял это ни в какой форме (путем тестирования или документации компилятора), но я нашел этот SO ответ , который подтверждает мои подозрения.
0 голосов
/ 08 ноября 2018

int myArray[N]; недопустимо в C ++. Это поведение было введено в C99, но никогда в C ++, возможно, потому, что оно заставляет много уродливых вещей происходить за кулисами, чтобы заставить его работать, и это в результате сделает сгенерированный код менее эффективным. На самом деле эта функция была даже отменена в C11, где ее поддержка является просто необязательной и больше не является обязательной. Вместо этого используйте std::vector<int> или любой другой стандартный контейнер по вашему выбору.

0 голосов
/ 08 ноября 2018

Размер статических массивов array[N] должен быть известен во время компиляции.

Используйте std::vector для динамических массивов:

// Example program
#include <iostream>
#include <string>
#include <vector>

int main()
{
    int N; std::cin >> N;
    std::cout << N << std::endl;
    std::vector<int> myArray(N);
    std::cout << myArray.size() << std::endl;
    return 0;
}
0 голосов
/ 08 ноября 2018

Это происходит потому, что в C++ размер статических массивов, объявленных с array[N], должен быть известен во время компиляции, и, таким образом, ваша ошибка, вероятно, является вашим компилятором, который говорит вам, что он должен знать размер заранее. Как указано, используйте std::vector, когда вам нужны динамические массивы.

...