Понимание 2D массива с динамическим выделением памяти


Может ли кто-нибудь помочь мне понять последнюю строку в этом фрагменте кода? Я не понимаю, как это динамически распределяет 2D-массив. Я понимаю, что в строке 6 он создает указатель с именем " a "и указывает на массив целых чисел размера 5, определенных "c".

Чего я не понимаю, так это как это утверждение "new int" работает с r, брошенным в уравнение. Заранее спасибо.

#include <iostream>
const int c = 5; //num of columns

 int main () {
   int r = 5;
   int (*a)[c];
   a = new int[r][c]; // allocate array
}
2 4

2 ответа:

Если у вас есть тип T и вы собираетесь выделить массив размером N , то это выражение

new T[N]

Возвращает адрес типа T * первого элемента выделенного массива.

Итак, вы должны написать

T *a = new T[N]; 

Например, если T эквивалентно типу int

typedef int T;

Или

using T = int;

Тогда вышеуказанное распределение можно записать

int *a = new int[N];

Размер элемента массива равен sizeof( int ) и обычно равен 4 байты.

Теперь предположим, что вы собираетесь выделить массив элементов типа int[M], где M является постоянным целочисленным выражением.

Вы можете написать

typedef int T[M];

Или

using T = int[M];

И

T *a = new T[N];
Таким образом, вы выделили массив N элементов, где каждый элемент имеет размер sizeof( int[M] и указатель a указывает на первый элемент массива.

Потому что T эквивалентно tp int [M] Вы можете написать

int ( *a )[M] = new int [N][M]; 

Вот это утверждение выделяет массив N элементов типа int[M] и указатель a получает адрес первого элемента выделенного массива.

Возвращаясь к примеру вашей программы

Int r = 5 int (*a) [c]; a = new int[r][c];

Вы можете переписать его следующим образом

typedef int T[c];

Или

using T = int[c];

И

T *a = new T[r];

То есть этот оператор выделяет массив r элементов (объектов) типа int[c] и a является указателем на первый элемент выделенного массива.

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

#include <iostream>
const int c = 5; //num of columns

int main () {
    int r = 5;

    //Creates a pointer to an array of 5 integer pointers.
    int (*a)[c];

    a = new int[r][c]; // allocate array

    std::cout << *a << std::endl;
    std::cout << a << std::endl;
    std::cout << std::endl;
    std::cout << "Displaying deferenced, unallocated array." << std::endl;
    for(int i=0; i<c;++i){
        std::cout << *a[i] << std::endl;
    }

    std::cout << "Diplaying pointers in the array." << std::endl;
    std::cout << "Note how it's not a 2d array." << std::endl;
    for(int i=0;i<c;++i){
        for(int j=0;j<r;++j){
            std::cout << a[i] << " ";
        }
        std::cout << std::endl;
    }


    std::cout << "Allocating array 1d, 1d style fails..." << std::endl;
    /*
    for(int i=0;i<c;++i){
        a[i] = 23; //Syntax error! Requires two indexes.
    }
    */

    std::cout << "Allocating 1d array 2d style... success!?" << std::endl;
    for(int i=0;i<r;++i){
        for(int j=0;j<c;++j){
            a[i][j] = 13;
        }
    }

    std::cout << "Displaying allocated array." << std::endl;
    for(int i=0;i<r;++i){
        for(int j=0;j<c;++j){
            std::cout << a[i][j] << " ";
        }
        std::cout << std::endl;
    }


    delete [] a;
} 

Выходы:

0x100202ba0
0x100202ba0

Displaying deferenced, unallocated array.
0
0
0
0
0
Diplaying pointers in the array.
Note how it's not a 2d array.
0x100202ba0 0x100202ba0 0x100202ba0 0x100202ba0 0x100202ba0 
0x100202bb4 0x100202bb4 0x100202bb4 0x100202bb4 0x100202bb4 
0x100202bc8 0x100202bc8 0x100202bc8 0x100202bc8 0x100202bc8 
0x100202bdc 0x100202bdc 0x100202bdc 0x100202bdc 0x100202bdc 
0x100202bf0 0x100202bf0 0x100202bf0 0x100202bf0 0x100202bf0 
Allocating array 1d, 1d style fails...
Allocating 1d array 2d style... success!?
Displaying allocated array.
13 13 13 13 13 
13 13 13 13 13 
13 13 13 13 13 
13 13 13 13 13 
13 13 13 13 13 
Program ended with exit code: 0