Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Функции управление памятью






Рассмотрим функции управления памятью:

· malloc() – предназначена для выделения непрерывной области памяти заданного размера, например, void * malloc(size_t size),

где size_t – тип результата операции sizeof, определяемый в различных объектах-заголовках (stdio.h, stdlib.h, string.h и др.) и соответствующий типу unsigned long; size – размер выделяемой памяти в байтах.

Функция malloc возвращает указатель без типа. Если выделить память не удалось, функция возвращает значение NULL.

При использовании в программах на C++ требуется выполнять явное преобразование типа указателя. Если необходимо создать символьную cтроку в динамической памяти, то сначала надо объявить указатель char *S1, а затем выделить область под символьную строку с помощью функции
malloc():

S1=(char*)malloc(V);

где V – выражение, значением которого является целые неотрицательные числа, например, V=10, V=10+7 и т. д.

Далее указатель S1 используется в функциях для работы со строками так же, как если бы строка была объявлена как массив символов или указатель на статическую строку, например:

gets (S1);

scanf (" %s", S1);

printf (" %s", S1);

int n=strlen(S1);

· calloc() – предназначена для выделения памяти под заданное количество объектов, каждый из которых имеет размер size байт, всего n ´ size байт. Возвращает указатель на первый байт выделенной область памяти.

Если выделить память не удалось, функция возвращает значение NULL:

void * calloc(size_t n, size_t size);

· realloc() – предназначена для изменения размера динамически выделенной области, адресуемой указателем ptr, при этом размер области может как увеличиваться, так и уменьшаться:

void* realloc(void* ptr, size_t size);

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

Функция возвращает адрес новой области памяти, при этом старая область освобождается. Данные из освобождаемой области копируются в новую, но не более size байт. В некоторых случаях область, адресуемая первоначально указателем ptr, может сохраниться, только изменится ее размер. Если выделить память не удалось, функция возвращает значение NULL.

Для того чтобы избежать ошибок в связи с перемещением данных в динамической памяти, функцию realloc() следует использовать так:

ptr2=realloc(ptr1, new_size);

if(ptr2! =NULL) /*Проверка выделения новой памяти*/

ptr1=ptr2; /*Запись адреса новой области памяти в исходный указатель*/

Таким образом, указатель ptr1 всегда будет хранить текущий адрес размещения данных, независимо от того, были данные перемещены функцией realloc() или нет.

· free() – предназначена для освобождения памяти, выделенной функциями malloc(), calloc(), realloc(). После выполнения функции освобожденная память может быть выделена вновь под другие данные:

void free(void* ptr);

где prt – указатель на область памяти, созданной только функциями динамического управления памятью malloc(), calloc(), realloc(). Использование других указателей в функции free делает ее поведение неопределенным и может привести к потере управления памятью.

Рассмотрим пример создания динамического числового массива. Функция calloc() выделяет память для 10 элементов типа int. Указатель ptr хранит адрес первого элемента массива. Значения элементов вводятся с клавиатуры. Затем вычисляется сумма всех элементов. После вывода результата на экран память, распределенная под массив, освобождается:

#include < stdlib.h>

#include < stdio.h>

int main(void)

{

int* ptr=(int*)calloc(10, sizeof(int));

int s=0;

for(int i=0; i< 10; i++)

scanf(" %d", & ptr[i]);

for(i=0; i< 10; i++)

s+=ptr[i];

printf(" Summa=%d\n", s);

free(ptr);

return 0;

}

После освобождения памяти значение адреса, присвоенное указателю ptr, не следует использовать, так как эта область может быть выделена под другую переменную. Рекомендуется в такой указатель записать значение пустого указателя NULL (в VC++6.0 это обязательно):

ptr=NULL;

Приведем пример программы, использующей динамическую строку. Дан статический массив строк. Отсортировать массив по возрастанию, использовать в качестве вспомогательной переменной (буфера) динамическую переменную:

#include < stdio.h>

#include < conio.h>

#include < alloc.h>

#include < string.h>

int main()

{

char *S1; /*Переменная-указатель*/

/*Статический массив строк*/

static char list[3][15]={" Ivanov", " Sidorov", " Petrov" };

int i, j;

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

S1=(char *)malloc (15);

for (i=0; i< 2; i++)

{

for (j=0; j< 2-i; j++)

{

if (strcmp(list[j], list[j+1])> 0)

{

strcpy(S1, list[j]);

strcpy(list[j], list[j+1]);

strcpy(list[j+1], S1);

}

}

}

for (i=0; i< 3; puts(list[i]), i++);

getch();

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

S1=NULL;

return 0;

}

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

 

 






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.