Одномерные динамические массивы
Цель лекции: изучить объявления, выделения и освобождения памяти для одномерных динамических массивов, обращения к элементам, научиться решать задачи с использованием одномерных динамических массивов в языке C++.
При использовании многих структур данных достаточно часто бывает, что они должны иметь переменный размер во время выполнения программы. В этих случаях необходимо применять динамическое выделение памяти. Одной из самых распространенных таких структур данных являются массивы, в которых изначально размер не определен и не зафиксирован.
В соответствии со стандартом языка массив представляет собой совокупность элементов, каждый из которых имеет одни и те же атрибуты. Все эти элементы размещаются в смежных участках памяти подряд, начиная с адреса, соответствующего началу массива. То есть общее количество элементов массива и размер памяти, выделяемой для него, получаются полностью и однозначно заданными определением массива. Но это не всегда удобно. Иногда требуется, чтобы выделяемая память для массива имела размеры для решения конкретной задачи, причем ее объем заранее не известен и не может быть фиксирован. Формирование массивов с переменными размерами (динамических массивов) можно организовать с помощью указателей и средств динамического распределения памяти.
Динамический массив – это массив, размер которого заранее не фиксирован и может меняться во время исполнения программы. Для изменения размера динамического массива язык программирования С++, поддерживающий такие массивы, предоставляет специальные встроенные функции или операции. Динамические массивы дают возможность более гибкой работы с данными, так как позволяют не прогнозировать хранимые объемы данных, а регулировать размер массива в соответствии с реально необходимыми объемами.
Объявление одномерных динамических массивов
Под объявлением одномерного динамического массива понимают объявление указателя на переменную заданного типа для того, чтобы данную переменную можно было использовать как динамический массив.
Тип * ИмяМассива;
ИмяМассива – идентификатор массива, то есть имя указателя для выделяемого блока памяти.
Тип – тип элементов объявляемого динамического массива. Элементами динамического массива не могут быть функции и элементы типа void.
Например:
int *a; double *d;
В данных примерах a и d являются указателями на начало выделяемого участка памяти. Указатели принимают значение адреса выделяемой области памяти для значений типа int и типа double соответственно.
Таким образом, при динамическом распределении памяти для динамических массивов следует описать соответствующий указатель, которому будет присвоено значение адреса начала области выделенной памяти.
Выделение памяти под одномерный динамический массив
Для того чтобы выделить память под одномерный динамический массив в языке С++ существует 2 способа.
1) при помощи операции new, которая выделяет для размещения массива участок динамической памяти соответствующего размера и не позволяет инициализировать элементы массива.
ИмяМассива = new Тип [ВыражениеТипаКонстанты];
ИмяМассива – идентификатор массива, то есть имя указателя для выделяемого блока памяти.
Тип – тип указателя на массив.
ВыражениеТипаКонстанты – задает количество элементов (размерность) массива. Выражение константного типа вычисляется на этапе компиляции.
Например:
int *mas; mas = new int [100]; /*выделение динамической памяти размером 100*sizeof(int) байтов*/ double *m = new double [n]; /*выделение динамической памяти размером n*sizeof(double) байтов*/ long (*lm)[4]; lm = new long [2] [4]; /*выделение динамической памяти размером 2*4*sizeof(long) байтов*/
При выделении динамической памяти размеры массива должны быть полностью определены.
2) при помощи библиотечной функции malloc (calloc), которая служит для выделения динамической памяти.
ИмяМассива = (Тип *) malloc(N*sizeof(Тип));
или
ИмяМассива = (Тип *) calloc(N, sizeof(Тип));
ИмяМассива – идентификатор массива, то есть имя указателя для выделяемого блока памяти.
Тип – тип указателя на массив.
N – количество элементов массива.
Например:
float *a; a=(float *)malloc(10*sizeof(float)); // или a=(float *)calloc(10,sizeof(float)); /*выделение динамической памяти размером 10*sizeof(float) байтов*/
Так как функция malloc (calloc) возвращает нетипизированный указатель void *, то необходимо выполнять преобразование полученного нетипизированного указателя в указатель объявленного типа.
Освобождение памяти, выделенной под одномерный динамический массив
Освобождение памяти, выделенной под одномерный динамический массив, также осуществляется 2 способами.
1) при помощи операции delete, которая освобождает участок памяти ранее выделенной операцией new.
delete [] ИмяМассива;
ИмяМассива – идентификатор массива, то есть имя указателя для выделяемого блока памяти.
Например:
delete [] mas; /*освобождает память, выделенную под массив, если mas адресует его начало*/ delete [] m; delete [] lm;
Квадратные скобки [] сообщают оператору, что требуется освободить память, занятую всеми элементами, а не только первым.
2) при помощи библиотечной функции free, которая служит для освобождения динамической памяти.
free (ИмяМассива);
ИмяМассива – идентификатор массива, то есть имя указателя для выделяемого блока памяти.
Например:
free (a); //освобождение динамической памяти