Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции_по_пяву_4.doc
Скачиваний:
101
Добавлен:
15.03.2015
Размер:
1.29 Mб
Скачать

Функция free

Объявление этой функции имеет следующий вид

#include<stdlib.h> voidfree(void* ptr);

Рассматриваемая функция предназначена для освобождения памяти, на которую установлен указатель ptr, Эта память должна быть предварительно выделена одной из следующих функций:calloc(),malloc() иrealloc(). Если значение параметраptrравноNULL, то функцияfree() никаких действий не выполняет. В противном случае, если указательptrне установлен на память, выделенную одной из функций, предназначенных для выделения динамической памяти, поведение функцииfree() не определенно. Значение указателяptrпосле успешного освобождения памяти считается неопределенным, такие указатели относятся к категории недействительных указателей. Рекомендуется после освобождения памяти указателюptrприсваивать значениеNULL.

Отметим, что функция free() не имеет средств, предназначенных для передачи информации о возникновении ошибки при освобождении памяти.

Рассмотрим пример применения функции free().

#include<stdlib.h>

#define MAXSIZE 129 intmain(void) {

char* buf;

if(NULL == (buf = malloc(MAXSIZE)))

error(); /* .................. */ /*Строка buf теперь не нужна */ free(buf); buf = NULL; /* .................. */ }

    1. Указатели – параметры функций. Имитация передачи по ссылке

В некоторых языках программирования, например в языке Паскаль, имеются два способа передачи параметров в функцию: передача по значению и по ссылке. В языке Си существует только один способ – передача параметров по значению. Применение указателей в языке Си открывает возможность имитировать (моделировать) передачу по ссылке. Это достигается путем установления с помощью указателя - параметра связи с памятью, выделенной в точке вызова функции. Это позволяет использовать указатели – параметры функций того, чтобы вернуть через параметры результаты вычислений, полученные в функции. Рассмотрим два примера.

Пример 1Обмен значений двух переменных.

Постановка задачи. Даны две переменныеaиbтипаdouble. Необходимо выполнить обмен значений этих переменных. Решение необходимо оформить в виде функции.

Решение.

Прежде всего, следует убедиться в том, что попытка решить эту задачу, используя функцию, имеющую следующий интерфейс

void swap(double a, double b);

закончится неудачей. Вернуть обмен значений параметров a и b, выполненный в теле функции swap() не удается.

void swap(double *p1, double *p2) { double temp = *p1; *p1 = *p2; *p2 = temp; } // Клиентский код int main(void) { double a = 2, b = 3; swap(&a, &b); }

Следует убедиться в том, что при использовании рассматриваемого варианта функции swap() обмен значений переменныхaиbимеет место. Этого удалось достичь за счет того, что адреса этих переменных во время вызова рассматриваемой функции оказались записанными в парметры функции. В результате в теле функцииswap() с помощью разыменования указателей осуществляется работа с памятью, выделенной в точке вызова. Обратимся, например, следующей инструкции , которая находится в теле функцииswap()

*p1 = *p2;

Нетрудно убедиться в том, что эта инстукция работает с переменными a и b, которые находятся в клиентском коде, выполняя копирование переменной b в переменную a.

Пример 2Обмен значений двух указателей.

Постановка задачи. Даны два указателяp1 иp1 типаdouble*. Решение необходимо оформиты в виде функции.

Решение.

void swap_pointers(double **p1, double **p2) { double* pt = *p1; *p1 = *p2; *p2 = *pt; } // Клиентский код int main(void) {

double a = 2; double *pa = &a; double b = 3; double *pb = &b; swap_pointers(&pa, &pb); // .. }