Подтвердить что ты не робот

Правильный способ инициализации динамического указателя на многомерный массив?

Мне не повезло с динамическими указателями, когда я меняю их на 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];

И это работает, но это не то, что я хочу выполнить. Делая это, я ограничусь хотя бы постоянным значением для любого последующего измерения, но я хочу, чтобы он был полностью определен во время выполнения и, следовательно, "динамический".

Как я могу пойти и сделать эту многомерную работу указателя?

4b9b3361

Ответ 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;
    }
}