Динамическое распределение памяти



 

До сих пор для данных, которые использовались, память выделялась при объявлении переменных. Такой способ выделения памяти называется статическим.

Однако иногда размер данных становится известным только во время выполнения программы. Например, если в процессе какого-либо измерения выполняется сохранение данных через определенные промежутки времени, объем этих данных зависит от времени, прошедшего с начала измерения. В таком случае рациональнее распределять память компьютера во время измерения. Процедура выделения памяти во время выполнения программы называется динамическим распределением (выделением) памяти.

В C++ существует два способа динамического выделения памяти. Один из них, унаследованный от С, использует стандартные библиотечные функции malloc и free. Другой – операторы new и delete, которые отсутствуют в С. Для обоих способов необходимо применение переменных типа указатель. Как правило, конкретные адреса, содержащиеся в этих переменных, не используются.

 

Использование стандартных функций malloc и free

 

Динамическое выделение памяти с помощью библиотечной функции malloc состоит из следующих шагов.

1. Включение в программу файла заголовков malloc.h директивой #include <malloc.h>.

2. Объявление указателя нужного типа, например int *p;

3. Вызов функции malloc с указанием в качестве параметра требуемого количества памяти в байтах. Так как функция выдает результат своей работы в виде указателя на тип void, выполняется приведение типа (преобразуется тип результата к типу, указанному в объявлении). Присваивается полученное значение объявленному указателю. Пример:

 

p=(int *) malloc (число элементов массива*sizeof(int));

 

Вместо int может быть подставлен любой стандартный или введенный программистом тип.

4. Проверка факта выделения памяти. Если выделение памяти в нужном объеме невозможно, функция malloc возвращает в качестве своего результата нулевой указатель NULL, соответствующий значению ложь. Если выделение памяти выполнено, продолжаем выполнение программы, если нет, выходим из нее с соответствующей диагностикой о недостатке памяти. Пример:

 

if (!p) сообщение, выход; else продолжение;

 

5. Освобождение памяти после окончания работы с ней. Для этого вызываем функцию fгее и используем указатель в качестве аргумента:

 

free (p);

 

Значение указателя, полученное после выполнения шага 3, должно сохраняться до выполнения шага 5. В противном случае вся память, выделенная по этому адресу, будет потеряна при выходе из программы, что, в конечном счете, может привести к недостатку памяти и нарушению работы операционной системы.

Наиболее частой причиной «зависания» компьютера при работе с динамически выделяемой памятью является несоответствие инструкций malloc и free (в обеих инструкциях должен использоваться один и тоже указатель) или недостаточный объем свободной памяти.

В качестве примера рассмотрим ввод/вывод одномерного динамического массива произвольной длины, задаваемой с клавиатуры.

 

int i,n,*massiv; //объявление указателя

cout<<RUS("Введите размер массива\n");cin>>n;//ввод размера массива

massiv=(int*)malloc(n*sizeof(int)); //выделение динам.памяти

if(!massiv)                     //проверка факта выделения памяти

{cout<<RUS("\nНедостаточно памяти");

 cout<<RUS("\nНажмите любую клавишу для завершения программы ...\n");

 getch();

 return 0;}

cout<<RUS("Введите массив\n");

for(i=0;i<n;i++)cin>>massiv[i];  //ввод массива

cout<<RUS("\nmassiv\n");

for(i=0;i<n;i++)cout<<' '<<massiv[i];  //вывод массива

free(massiv);                   //освобождение памяти

 

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

Для динамического выделения памяти можно также использовать функцию calloc( ). В отличии от malloc функция calloc кроме выделения области памяти под массив объектов еще производит инициализацию элементов массива нулевыми значениями.

В зависимости от используемой версии C++ для работы с большими фрагментами динамической памяти возможно применение функций farmalloc( ), farcalloc( ), farcoreleft( ) и farfree().

 


Дата добавления: 2018-11-24; просмотров: 266; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!