Вызов массива с переменным размером в качестве параметра

Я пытался сделать программу, в которой пользователь решает размеры двумерного массива. Я получаю сообщение об ошибке при определении функции во время компиляции. Почему это неправильно и как правильно это сделать?

Я использую компилятор Dev-C++ 5.7.1 (если это актуально).

#include<iostream>

using namespace std;

int R=0,C=0;                 

void func(int);

int main() {
    cin>>R>>C;
    int array[C][R];
                      // DO STUFF HERE
    func(array);
                      // DO SOME MORE STUFF
    return 0;
}

void func(int arr[][R]) {  
                     // DO STUFF HERE
}

3 ответа

ISO-C++ запрещает VLA. Чтобы динамически распределить массив, вам нужно будет сделать несколько простых трюков с указателями или использовать вектор векторов.

вектор векторов приближения:

std::cin >> R >> C;
std::vector<std::vector<int>> array(R, std::vector<int>(C));

Подпись для func затем становится (правильность const может отличаться)

void func(const std::vector<std::vector<int>>& v);

Вышеуказанное является более простым, более легким в обслуживании, безопасным и более коротким решением.


С помощью указателей и указателей на указатели вы можете сделать это, но это становится более сложным, и вам нужно delete все что ты new

int R, C;
std::cin >> R >> C;
int **array = new int*[R]; // allocates space for R row pointers
for (int i = 0; i < R; ++i) {
    array[i] = new int[C]; // for each row, allocate C columns
}

func(R, C, array);

//then delete everything
for (int i = 0; i < R; ++i) {
    delete [] array[i]; // delete all of the ints themselves
}
delete [] array; // delete the row pointers.

с подписью для функционала

void func(int r, int c, int **arr);

Опять же, вектор векторов будет намного проще для вас.

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

int array[SIZE];

когда массив находится в стеке, компилятор должен заранее знать, каков его размер, поэтому SIZE должен быть постоянным выражением (известным во время компиляции), а иногда и определенным значением (устанавливается с помощью #define SIZE 10).
если вы хотите создать массив неизвестного размера (будет определен во время выполнения), вам нужно создать массив в куче, например:

int **array = new int*[C];
for(int i = 0;i<C; i++)
  array[i] = new int[R];

позже вы должны не забыть удалить все, что вы динамически выделяли (все, что вы использовали новые)

for(int i = 0;i<C; i++)
  delete[] array[i];
delete[] array;

обратите внимание на использование delete[], потому что мы удаляем массив (массив - это массив массивов целых, массив [i] - это массив целых)

Я бы порекомендовал передать указатель на массив и две переменные для R и C. Тогда вам нужно убедиться, что вы правильно используете указатель, чтобы оставаться в пределах массива. В противном случае установите это как шаблон, но вам все равно, вероятно, нужно будет знать размеры R & C.

Другие вопросы по тегам