Связь указателей и массивов с одним измерением справедливо и для массивов с бóльшим числом измерений.
Если рассматривать предыдущий массив (int a [2][3];) как массив двух массивов размерностью по три элемента каждый, то обращение к элементу а [ i ][ j ] соответствует эквивалентное выражение *(*(а + i)+ j), а объявление этого массива с использованием указателей будет иметь вид
int ** а;
Таким образом, имя двухмерного массива – ID указателя на указатель.
Динамическое размещение данных
Для создания массивов с переменной размерностью используется динамическое размещение данных, декларируемых указателями.
Для работы с динамической памятью используются стандартные функции библиотеки alloc. h:
void * malloc (size) и void * calloc ( n, size ) – выделяют блок памяти размером size и n ´ size байт соответственно; возвращают указатель на выделенную область, при ошибке – значение NULL;
void free (bf); – освобождает ранее выделенную память с адресом bf.
Другим, более предпочтительным подходом к динамическому распределению памяти является использование операций языка С++ new и delete.
|
|
Операция new возвращает адрес ОП, отведенной под динамически размещенный объект, при ошибке – NULL, а операция delete освобождает память.
Минимальный набор действий, необходимых для динамического размещения одномерного массива действительных чисел размером n:
double *а;
...
а = new double[n]; // Захват памяти для n элементов
...
delete []а; // Освобождение памяти
Минимальный набор действий, необходимых для динамического размещения двухмерного массива действительных чисел размером n´m:
int i, n, m; // n, m – размеры массива
double **a;
a = new double *[n]; // Захват памяти под указатели
for(i=0; i<n; i++) a[i] = new double [m]; // и под элементы
...
for(i=0; i<n; i++) delete []a[i]; // Освобождение памяти
delete []a;
Для современных компиляторов (версий старше «6») для освобождения памяти достаточно записать только delete [] a;