Лекции по проге / 15_Динамические структуры данных
.pdf
Уничтожение динамического массива
//Освобождаем память free(arr);
//Предотвращаем обращение к массиву arr = NULL;
21
Правила освобождения памяти
Нельзя уничтожить часть динамического массива — только массив целиком
В функцию free передаются именно адреса, возвращаемые функциями malloc или calloc, и никакие другие
Нельзя передавать в функцию free адреса, полученные прибавлением (вычитанием) смещений к адресам, возвращаемым функциями malloc и calloc
На каждый вызов malloc/calloc должен быть соот- 22 ветствующий вызов free
Правила освобождения памяти
Попытка обратиться по указателю, указывающему на ранее освобожденную память (например, если в программе существовало два указателя на один участок памяти) вызовет ошибку нарушения прав доступа с завершением работы программы
Выделенную память освобождать обязательно
Не освобожденная память приводит к ошибке типа утечка памяти (memory leak), особенно опасной для
23 серверных программ
Задание
Определить значения по адресам для следующей программы:
int *ptr = (int *) malloc( sizeof(int) );
int **pptr = (int **) malloc( sizeof(int *) * 3); int *ptr10 = (int *) malloc( sizeof(int) * 10); int *ptr2;
/*1*/ |
pptr[0] = ptr10; |
/*2*/ |
pptr[1] = ptr; |
/*3*/ |
ptr = ptr10; |
/*4*/ |
pptr[0][1] = 5; |
/*5*/ |
pptr[1][0] = 7; |
24 /*6*/ |
ptr2 = *pptr; |
Карта памяти после выделения памяти
ptr 

? 
0 1 2
pptr 

?
?
? 
ptr10 |
|
|
|
|
|
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
|
||||||||||
|
|
|
|
|
|
? |
|
? |
|
? |
|
? |
|
? |
|
? |
|
? |
|
? |
|
? |
|
? |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ptr2
25
Карта памяти после перестановки указателей и присвоения значений
|
3 |
5 |
ptr |
7 |
3 2
0 1 2
pptr 







? 
|
1 |
|
|
|
|
|
|
|
|
|
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
ptr10 |
? 5 ? ? ? ? ? ? ? ? |
||||||||
|
|
4 |
|
|
|
|
|
|
|
6
ptr2
26
Задание
Освобдить память для следующей программы:
int *ptr = (int *) malloc( sizeof(int) );
int **pptr = (int **) malloc( sizeof(int *) * 3); int *ptr10 = (int *) malloc( sizeof(int) * 10); int *ptr2;
/*1*/ |
pptr[0] = ptr10; |
/*2*/ |
pptr[1] = ptr; |
/*3*/ |
ptr = ptr10; |
/*4*/ |
pptr[0][1] = 5; |
/*5*/ |
pptr[1][0] = 7; |
27 /*6*/ |
ptr2 = *pptr; |
Ситуация перед освобождением памяти
В программе производится 3 операции выделения памяти:
целое число - ptr;
динамический массив из 10 целых чисел - ptr10;
динамический массив из 3-х указателей на целое число - pptr.
Значение указателя на одно целое число заменяется в переменной ptr указателем на массив чисел; но перед этим оно сохраняется во втором элементе массива указателей
Переменная ptr2 дублирует указатель ptr10 на массив
28 из 10 целых чисел
Пример освобождения памяти
//1 - освобождаем одно число free( pptr[1] );
//2 - освобождаем массив из 10 чисел free( ptr10 ); // или ptr2, или pptr[0]
//3 - освобождаем массив из 3 указателей free( pptr );
29
Карта памяти после освобождения памяти
ptr |
7 |
|
|
|
|
1 |
|
3 |
0 |
1 |
2 |
pptr |
|
|
? |
ptr10 |
|
|
|
2 |
|
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
|
|||||||||||
|
|
|
|
|
? |
|
5 |
|
? |
|
? |
|
? |
|
? |
|
? |
|
? |
|
? |
|
? |
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ptr2
30
