Динамическое выделение памяти под многомерные массивы

Указатель на указатель или адрес адреса

 

Объявление в программе: int **point -означает, что переменная point используется для хранения адреса адреса. Указателю point при распределении памяти будет выделено также 4 байта. Проиллюстрируем возможность использования таких указателей следующей программой.

 

/* программа # 1.18 */

void main()

{

int a,*point_1,**point_2,***point_3;

 

a = 5;

point_1 = &a;/* инициализируем указатель адресом переменной а */

point_2 = &point_1; /* это адрес адреса переменной а */

point_3 = &point_2; /* это адрес адреса адреса переменной а */

***point_3 = 10; /* присваиваем переменной а значение 10 */

 

}

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

 

 

Часто двойная косвенная адресация используется для выделения памяти под двумерные массивы, тройная - под трехмерные и т. д. Программа # 1.19 иллюстрирует выделение памяти под двумерный массив типа float, возврат память OS и печать матрицы. Основная идея программы - представление двумерного массива как совокупности некоторого числа одномерных массивов- строк матрицы. Подробности содержатся в комментариях программы.

 

/* программа # 1.19 */

 

#include <vcl.h>

#include <conio.h>

#include <stdio.h>

#pragma hdrstop

#pragma argsused

 

// Протипы функций, используемых в программе

float ** Get_mem ( int n, int m );

void Del_mem ( float ** A, int n );

void print_matrix (float **A, int n, int m, char *format);

 

int main(int argc, char* argv[])

{

int n,m;

 

n =10; m=10;

float ** Matrix = Get_mem ( n, m); // Выделяем память под двумерный массив //10*10

 

for ( int i =0; i < n ; i ++) // строим единичную матрицу- на главной диагонали, которой - единицы

for ( int j =0; j < m ; j ++)

if ( i == j ) Matrix [i][j]= 1.0;

 

print_matrix (Matrix, n, m, "%3.1f ");

 

Del_mem (Matrix,n); // Возвращаем память ОС

getch ();

 

return 0;

}

 

// Выделяем память для матрицы в n строк и m – столбцов

float ** Get_mem ( int n, int m )

{

float ** buffer;

 

buffer = new float *[n]; // выделяем память под массив из n элементов. Этот //массив будет хранить адреса строк (массивов) матрицы. Поэтому в операторе //new тип данных float *(адреса данных типа float). Адрес данного массива записываем в переменную buffer, смысл которой - адрес адресов (массив указателей).

 

for ( int i =0; i < n ; i ++) // выделяем память n –раз под массивы из m //элементов - строки матрицы

buffer[i] = new float [m];

 

// Обнуляем матрицу

for ( int i =0; i < n ; i ++)

for ( int j =0; j < m ; j ++)

buffer[i][j] = 0.0;

 

return buffer; // возвращаем адрес массива указателей

}

 

// возвращаем память OS

void Del_mem ( float ** A, int n )

{

for ( int i =0; i < n ; i ++) // удаляем память – строки матрицы

delete[] A[i]; // Так правильно удаляется память, выделенная под массив

// delete[]

delete[] A; // удаляем сам массив указателей

 

return;

}

 

// Вывод матрицы на экран

void print_matrix (float **A, int n, int m, char *format)

{

for ( int i =0; i < n ; i ++)

{

for ( int j =0; j < m ; j ++)

printf (format, A[i][j]);

printf ("\n");

}

return;

}