Динамическое выделение и освобождение памяти в стиле C
Язык C++ поддерживает и “старый”, заимствованный от языка C, стиль работы с динамической областью. Достаточно часто бывает полезно использовать именно этот механизм управления динамической памятью, так как он предоставляет несколько более широкий спектр “услуг”.
В языке C отсутствуют инструкции new и delete. Вместо них для управления динамической памятью используются библиотечные функции, имеющие следующие прототипы:
void *malloc ( size_t size );
void *calloc( size_t num, size_t size );
void free( void *memblock );
void *realloc( void *memblock, size_t size );
Функция mallocвыделяет в динамической области sizeбайт памяти (тип данных size_t представляет собой разновидность беззнакового целого типа данных) и возвращает адрес этого участка в виде нетипизированного указателя (void *). Поскольку возвращаемый указатель не привязан ни к какому типу данных, при работе с ним потребуется явное приведение типов данных (см. пример ниже).
Функция calloc выделяет в динамической области size * numбайт памяти и возвращает адрес этого участка в виде не типизированного указателя (void *).
Функция free освобождает участок динамической памяти по адресу memblock и возвращает его в список свободной памяти для повторного использования.
Функция realloc позволяет изменить размер (уменьшить или увеличить) ранее выделенной по адресу memblock памяти, установив новый размер выделенного участка равным sizeбайт. При увеличении размера выделенного участка данные, которые хранились в старом участке, копируются в новый участок памяти. При уменьшении объема выделенного участка, данные которые хранились в нем, усекаются до нового размера. Функция возвращает нетипизированный указатель на область памяти нового размера.
Предыдущий пример, переделанный под стиль C, выглядит так:
struct t_Person //Тип данных для "персоны"
{
char Fam[20];// Фамилия
char Name[20];// Имя
int Year;// Год рождения
};
setlocale ( 0, "" );// Русификация консоли
t_Person *p; //Определяем указатель на тип t_Person
p = ( t_Person * ) malloc ( sizeof ( t_Person ) ); //Выделяем память и используем
// приведение нетипизированного указателя к указателю на тип данных t_Person
strcpy ( p -> Fam, "Иванов" );// Заносим фамилию
strcpy ( p -> Name, "Иван" );// Заносим имя
p -> Year = 1995;// Заносим год рождения
cout << "Фамилия: " << p -> Fam << endl;// Выводим фамилию
cout << "Имя: " << p -> Name << endl;// Выводим имя
cout << "Год рождения: " << p -> Year << endl;// Выводим год рождения
free ( p );// Освобождаем память
Для переделки программы под стиль C потребовались всего два изменения в программе (эти места выделены красным цветом).
В одной и той же программе не рекомендуется смешивать использование “старого” и “нового” стилей работы с динамической памятью (возможны проблемы с совместимостью).
Другие возможности (некоторые преимущества) этого стиля работы с динамической памятью будут рассмотрены далее при изучении динамических массивов.
Дата добавления: 2019-02-07; просмотров: 373;