![]() Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Функции управление памятью
Рассмотрим функции управления памятью: · malloc() – предназначена для выделения непрерывной области памяти заданного размера, например, void * malloc(size_t size), где size_t – тип результата операции sizeof, определяемый в различных объектах-заголовках (stdio.h, stdlib.h, string.h и др.) и соответствующий типу unsigned long; size – размер выделяемой памяти в байтах. Функция malloc возвращает указатель без типа. Если выделить память не удалось, функция возвращает значение NULL. При использовании в программах на C++ требуется выполнять явное преобразование типа указателя. Если необходимо создать символьную cтроку в динамической памяти, то сначала надо объявить указатель char *S1, а затем выделить область под символьную строку с помощью функции 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, которые будут рассмотрены позже.
|