Правильный способ инициализации динамического указателя на многомерный массив?
Мне не повезло с динамическими указателями, когда я меняю их на 2 измерения и выше. Например, я хочу указатель на 2D-массив. Я знаю, что:
int A[3][4];
int (*P)[4] = A;
Полностью закончен (даже если я не совсем понимаю почему). Принимая во внимание, что:
int *P = new int[4];
работает, я подумал, что:
int **P = new int[5][7];
Будет также работать, но это не так. Этот код указывает на ошибку:
Error: A value of type "(*)[7]" cannot be used to initialize an entity of
type "int **"
Увидев это, новая часть становится указателем на массив из 7 целых чисел, которые я сделал:
int (*P)[4] = new int[7][4];
И это работает, но это не то, что я хочу выполнить. Делая это, я ограничусь хотя бы постоянным значением для любого последующего измерения, но я хочу, чтобы он был полностью определен во время выполнения и, следовательно, "динамический".
Как я могу пойти и сделать эту многомерную работу указателя?
Ответы
Ответ 1
Начнем с некоторых основных примеров.
Когда вы скажете int *P = new int[4];
-
new int[4];
вызывает оператор new function()
- выделяет память для 4 целых чисел.
- возвращает ссылку на эту память.
-
чтобы связать эту ссылку, вам нужно иметь тот же тип указателя, что и ссылка возврата, чтобы вы выполняли
int *P = new int[4]; // As you created an array of integer
// you should assign it to a pointer-to-integer
Для многомерного массива вам нужно выделить массив указателей, а затем заполнить этот массив указателями на массивы, например:
int **p;
p = new int*[5]; // dynamic `array (size 5) of pointers to int`
for (int i = 0; i < 5; ++i) {
p[i] = new int[10];
// each i-th pointer is now pointing to dynamic array (size 10)
// of actual int values
}
Вот как это выглядит:
![enter image description here]()
Чтобы освободить память
-
Для одномерного массива
// need to use the delete[] operator because we used the new[] operator
delete[] p; //free memory pointed by p;`
-
Для 2d-массива
// need to use the delete[] operator because we used the new[] operator
for(int i = 0; i < 5; ++i){
delete[] p[i];//deletes an inner array of integer;
}
delete[] p; //delete pointer holding array of pointers;
Избегайте утечки памяти и оборванных указателей!
Ответ 2
Вам нужно что-то вроде:
int **P = new int*[7];
p[0] = new int[5];
p[1] = new int[5];
...
Ответ 3
Другим подходом было бы использование 1D-массива в качестве 2D-массива. Таким образом вам нужно только выделить память один раз (один непрерывный блок);
int *array;
size_t row=5,col=5;
array = (int*)malloc(row*col*sizeof(int)) //or new int[row*col]
Это приведет к тому же, что и "int array [5] [5]".
для доступа к полям, которые вы только что делаете:
array[1 //the row you want
* col //the number of columns
+2//the column you want
] = 4;
Это равно:
array[1][2];
Ответ 4
Выполняет проверку границ некоторых компиляторов отладки, использует динамический размер и автоматически удаляет себя. Единственный результат - x и y - наоборот.
std::vector<std::vector<int>> array2d(y_size, std::vector<int>(x_size));
for (int y = 0; y < y_size; y++)
{
for (int x = 0; x < x_size; y++)
{
array2d[y][x] = 0;
}
}