Опубликован: 02.02.2011 | Доступ: свободный | Студентов: 2845 / 597 | Оценка: 4.43 / 3.57 | Длительность: 33:06:00
Специальности: Программист
Лекция 27:

Двумерные динамические массивы

< Лекция 26 || Лекция 27: 123 || Лекция 28 >
Аннотация: В лекции рассматриваются определение, объявления, инициализация двумерных динамических массивов, способы и этапы выделения и освобождения динамической памяти под двумерный массив, доступ к элементам двумерного динамического массива.

Цель лекции: изучить объявление, выделение и освобождение памяти под двумерные динамические массивы, обращение к элементам, научиться решать задачи с использованием двумерных динамических массивов на языке C++.

Под двумерным массивом понимается одномерный массив, элементами которого являются одномерные массивы. Другими словами, это набор однотипных данных, имеющий общее имя, и доступ к элементам которого осуществляется по двум индексам. Иногда двумерный массив также называют матрицей.

Динамическим массивом называют массив с переменным размером, то есть количество элементов может изменяться во время выполнения программы.

Для создания двумерного динамического массива вначале нужно распределить память для массива указателей на одномерные массивы, а затем выделить память для одномерных массивов. При динамическом распределении памяти для массивов следует описать соответствующий указатель, которому будет присвоено значение адреса начала области выделенной памяти.

Объявление двумерных динамических массивов

Под объявлением двумерного динамического массива понимают объявление двойного указателя, то есть объявление указателя на указатель.

Синтаксис:

Тип ** ИмяМассива;

ИмяМассиваидентификатор массива, то есть имя двойного указателя для выделяемого блока памяти.

Тип – тип элементов объявляемого динамического массива. Элементами динамического массива не могут быть функции и элементы типа void.

Например:

int **a; 
float **m;

Выделение памяти под двумерный динамический массив

При формировании двумерного динамического массива сначала выделяется память для массива указателей на одномерные массивы, а затем в цикле с параметром выделяется память под одномерные массивы. На рис. 26.1 представлена схема динамической области памяти, выделенной под двумерный массив.

Выделение памяти под двумерный массив

Рис. 26.1. Выделение памяти под двумерный массив

При работе с динамической памятью в языке С++ существует 2 способа выделения памяти под двумерный динамический массив.

1) при помощи операции new, которая позволяет выделить в динамической памяти участок для размещения массива соответствующего типа, но не позволяет его инициализировать.

Синтаксис выделения памяти под массив указателей:

ИмяМассива = new Тип * [ВыражениеТипаКонстанты];

Синтаксис выделения памяти для массива значений:

ИмяМассива[ЗначениеИндекса] = new Тип [ВыражениеТипа
Константы];

ИмяМассиваидентификатор массива, то есть имя двойного указателя для выделяемого блока памяти.

Тип – тип указателя на массив.

ВыражениеТипаКонстанты – задает количество элементов (размерность) массива. Выражение константного типа вычисляется на этапе компиляции.

Например:

int n, m;//n и m – количество строк и столбцов матрицы 
float **matr; //указатель для массива указателей
matr = new float * [n]; //выделение динамической памяти 
                          под массив указателей
for (int i=0; i<n; i++)
  matr[i] = new float [m]; //выделение динамической памяти 
                           для массива значений

При выделении динамической памяти размеры массивов должны быть полностью определены.

2) при помощи библиотечной функции malloc (calloc), которая предназначена для выделения динамической памяти.

Синтаксис выделения памяти под массив указателей:

ИмяМассива = (Тип **) malloc(N*sizeof(Тип *));

или

ИмяМассива = (Тип **) calloc(N, sizeof(Тип *));

Синтаксис выделения памяти для массива значений:

ИмяМассива[ЗначениеИндекса]=(Тип*)malloc(M*sizeof(Тип));

или

ИмяМассива[ЗначениеИндекса]=(Тип*)calloc(M,sizeof(Тип));

ИмяМассиваидентификатор массива, то есть имя двойного указателя для выделяемого блока памяти.

Тип – тип указателя на массив.

N – количество строк массива;

M – количество столбцов массива.

Например:

int n, m;//n и m – количество строк и столбцов матрицы 
float **matr; //указатель для массива указателей
matr = (float **) malloc(n*sizeof(float *)); 
//выделение динамической памяти под массив указателей
for (int i=0; i<n; i++)
  matr[i] = (float *) malloc(m*sizeof(float));
  //выделение динамической памяти для массива значений

Так как функция malloc (calloc) возвращает нетипизированный указатель void *, то необходимо выполнять его преобразование в указатель объявленного типа.

Освобождение памяти, выделенной под двумерный динамический массив

Удаление из динамической памяти двумерного массива осуществляется в порядке, обратном его созданию, то есть сначала освобождается память, выделенная под одномерные массивы с данными, а затем память, выделенная под одномерные массив указателей.

Освобождение памяти, выделенной под двумерный динамический массив, также осуществляется 2 способами.

1) при помощи операции delete, которая освобождает участок памяти ранее выделенной операцией new.

Синтаксис освобождения памяти, выделенной для массива значений:

delete ИмяМассива [ЗначениеИндекса];

Синтаксис освобождения памяти, выделенной под массив указателей:

delete [] ИмяМассива;

ИмяМассиваидентификатор массива, то есть имя двойного указателя для выделяемого блока памяти.

Например:

for (int i=0; i<n; i++)
  delete matr [i]; 
   //освобождает память, выделенную для массива значений 
delete [] matr;
//освобождает память, выделенную под массив указателей

Квадратные скобки [] означают, что освобождается память, занятая всеми элементами массива, а не только первым.

2) при помощи библиотечной функции free, которая предназначена для освобождения динамической памяти.

Синтаксис освобождения памяти, выделенной для массива значений:

free (ИмяМассива[ЗначениеИндекса]);

Синтаксис освобождения памяти, выделенной под массив указателей:

free (ИмяМассива);

ИмяМассиваидентификатор массива, то есть имя двойного указателя для выделяемого блока памяти.

Например:

for (int i=0; i<n; i++)
  free (matr[i]); 
   //освобождает память, выделенную для массива значений 
free (matr);
//освобождает память, выделенную под массив указателей
< Лекция 26 || Лекция 27: 123 || Лекция 28 >
Денис Курбатов
Денис Курбатов
Владислав Нагорный
Владислав Нагорный

Подскажите, пожалуйста, планируете ли вы возобновление программ высшего образования? Если да, есть ли какие-то примерные сроки?

Спасибо!