Динамическое выделение памяти под многомерные массивы
Указатель на указатель или адрес адреса
Объявление в программе: 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;
}