Объясните как работает создание двумерного динамического массива(int (*array)[7] = new int[15][7];)

Есть такой тип объявление двумерного динамического массива:

    unsigned n{3};       // количество строк
 
    int (*a)[2] = new int[n][2];
 
    int k{};
    // устанавливаем значения
    for (unsigned i{}; i < n; i++)
    {
        // устанавливаем данные для столбцов i-й строки
        for (unsigned j{}; j < 2; j++)
        {
            a[i][j] = ++k;
        }
    }

Можете подробно объяснить как работает конкретно этот пример, а именно часть с объявлением.

Как я понял, создается указатель на массив из двух элементов типа int, потом в new int[n] этот указатель на 2 элемента int множится до n(и соответственно также появляются массивы на которые указывают эти указатели) и потом их уже заполняют циклом. Почему количество столбцов ограничено константой и правильно ли я понял механику работы данного объявления?


Ответы (1 шт):

Автор решения: AlexGlebe

Запись int (*a)[2] = new int[n][2]; создаёт двумерный массив из n строк, в которых находится 2 int-а. Чтобы было более понятно можно сделать другой аналогичной записью :

typedef int row [ 2 ] ;
row * a = new row [ n ] ;

И a[1] будет иметь тип row == int[2], а a[1][1] тип int.
Массив int[2] будет содержать два int-а и выглядеть в памяти так :

[0][1]

А массив типа row аналогично :

[0][0] [0][1] [1][0] [1][1] .. [n-1][0] [n-1][1]

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

адрес[i][j] = начало + i * размер типа row + j * размер типа int

В языке C++ отказались от плавающего размера типа row, а в Си пока можно использовать так :

int n=fun();
int m=fum();
int ar[n][m];

Причин отказа много, не я решал этот вопрос, а создатели языка.

→ Ссылка