3.2.1.3. Освобождение памяти: free()

3.2.1.3. Освобождение памяти: free()

Когда вы завершили использование памяти, «верните ее обратно», используя функцию free(). Единственный аргумент является указателем, предварительно полученным с использованием другой функции выделения. Можно (хотя это бесполезно) передать функции free() пустой указатель:

free(coordinates);

coordinates = NULL; /* не требуется, но хорошая мысль */

После вызова free(coordinates) доступ к памяти, на которую указывает coordinates, запрещен. Она теперь «принадлежит» процедурам выделения, и они могут поступать с ней как сочтут нужным. Они могут изменить содержимое памяти или даже удалить ее из адресного пространства процесса! Таким образом, есть несколько типичных ошибок, которых нужно остерегаться при использовании free():

Доступ к освобожденной памяти

Если она не была освобождена, переменная coordinates продолжает указывать на блок памяти, который больше не принадлежит приложению. Это называется зависшим указателем (dangling pointer). На многих системах вы можете уйти от наказания, продолжая использовать эту память, по крайней мере до следующего выделения или освобождения памяти. На других системах, однако, такой доступ не будет работать. В общем, доступ к освобожденной памяти является плохой мыслью: это непереносимо и ненадежно, и GNU Coding Standards отвергает его. По этой причине неплохо сразу же установить в указателе программы значение NULL. Если затем вы случайно попытаетесь получить доступ к освобожденной памяти, программа немедленно завершится с ошибкой нарушения сегментации (надеемся, до того, как вы успели вашу программу выпустить в свет).

Освобождение одного и того же указателя дважды

Это создает «неопределенное поведение». После передачи блока памяти обратно выделяющим процедурам они могут объединить освобожденный блок с другой свободной памятью, которая есть в их распоряжении. Освобождение чего-то уже освобожденного ведет к неразберихе и в лучшем случае к крушению; известно, что так называемые двойные освобождения приводили к проблемам безопасности.

Передача указателя, полученного не от функций malloc(), calloc() или realloc()

Это кажется очевидным, но тем не менее важно. Плоха даже передача указателя на адрес где-то в середине динамически выделенной памяти:

free(coordinates + 10);

/* Освободить все кроме первых 10 элементов */

Этот вызов не будет работать и, возможно, приведет к пагубным последствиям, таким как крушение. (Это происходит потому, что во многих реализациях malloc() «учетная» информация хранится перед возвращенными данными. Когда free() пытается использовать эту информацию, она обнаружит там недействительные данные. В других реализациях, где учетная информация хранится в конце выделенного блока; возникают те же проблемы.)

Выход за пределы буфера

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

Отказ в освобождении памяти

Любая динамическая память, которая больше не нужна, должна быть освобождена. В частности, необходимо тщательно управлять памятью и освобождать ее, когда она выделяется внутри циклов или рекурсивных или глубоко вложенных вызовов функций. Отказ от этого ведет к утечкам памяти, при которых память процесса может неограниченно расти; в конце концов, процесс завершается из-за нехватки памяти. Эта ситуация может быть особенно разрушительной, если память выделяется для ввода записи или как-то еще связана с вводом: утечка памяти будет незаметна при использовании незначительных объемов ввода, но внезапно станет очевидной (и приведет в замешательство) при больших. Эта ошибка еще хуже для систем, которые должны работать непрерывно, как в системах телефонных коммутаторов. Утечка памяти, вызывающая крушение такой системы, может привести к значительным денежным или другим потерям.

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

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

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

Обсуждение ряда полезных инструментов для отладки динамической памяти см в разделе 15.5.2 «Отладчики выделения памяти».

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

4.1.3 Освобождение индексов

Из книги Архитектура операционной системы UNIX автора Бах Морис Дж

4.1.3 Освобождение индексов В том случае, когда ядро освобождает индекс (алгоритм iput, Рисунок 4.4), оно уменьшает значение счетчика ссылок для него. Если это значение становится равным 0, ядро переписывает индекс на диск в том случае, когда копия индекса в памяти отличается от


6.5.6 Освобождение области

Из книги Iptables Tutorial 1.1.19 автора Andreasson Oskar

6.5.6 Освобождение области Если область не присоединена уже ни к какому процессу, она может быть освобождена ядром и возвращена в список свободных областей (Рисунок 6.25). Если область связана с индексом, ядро освобождает и индекс с помощью алгоритма iput, учитывая значение


Приложение G. GNU Free Documentation License

Из книги Защита вашего компьютера автора Яремчук Сергей Акимович

Приложение G. GNU Free Documentation License Version 1.1, March 2000Copyright (C) 2000 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not


AVG Free Edition

Из книги 200 лучших программ для Интернета. Популярный самоучитель автора Краинский И

AVG Free Edition Перейдем к одной из разработок чешской компании Grisoft – бесплатному антивирусу AVG Free Edition. Эта антивирусная программа обладает хорошей функциональностью, однако пользователь бесплатной версии может работать только с английским интерфейсом. AVG Free Edition лишена


AVG Free Edition

Из книги Как найти и скачать в Интернете любые файлы автора Райтман М. А.

AVG Free Edition Производитель: Grisoft (http://www.grisoft.com/).Статус: бесплатная.Страница для скачивания: http://www.grisoft.com/doc/Programs/lng/us/tpl/tpl01.Размер: 16,6 Мбайт.При оценке нового, малоизвестного антивируса принято сравнивать его с такими известными программами, как «Антивирус Касперского». В таком


A-squared Free

Из книги Linux: Полное руководство автора Колисниченко Денис Николаевич

A-squared Free Производитель: Emsi Software GmbH (http://www.emsisoft.com).Статус: бесплатная.Страница для скачивания: http://www.emsisoft.com/en/software/download/.Размер дистрибутива: 16,3 Мбайт.Специализация антивирусного пакета a-squared Free – защита компьютера от разнообразных почтовых инфекций: троянов, червей,


Антивирусный пакет AVG Free

Из книги QNX/UNIX [Анатомия параллелизма] автора Цилюрик Олег Иванович

Антивирусный пакет AVG Free В последнее время работа большинства вредоносных программ направлена на получение денежных средств. Если раньше среди вредоносных программ преобладали вирусы, выполняющие различные деструктивные функции, то сейчас массовые эпидемии в основном


9.2.2. Информация о ресурсах системы: команды free, df, du

Из книги Ubuntu 10. Краткое руководство пользователя автора Колисниченко Д. Н.

9.2.2. Информация о ресурсах системы: команды free, df, du Команда free показывает общее количество занятой и свободной памяти: физической, в разделе подкачки и в буферах ядра. По умолчанию объем памяти выводится в килобайтах, а ключи -b и -m позволяют измерять его в байтах и


Освобождение мьютекса

Из книги Программирование для Linux. Профессиональный подход автора Митчелл Марк

Освобождение мьютекса int pthread_mutex_unlock(pthread_mutex_t* mutex);Функция pthread_mutex_unlock() освобождает мьютекс, на который ссылается переменная mutex. Вызвавший поток должен быть владельцем мьютекса. Если есть потоки, блокированные в ожидании освобождения мьютекса, то поток с наивысшим


Освобождение блокировки

Из книги Цифровая фотография. Трюки и эффекты автора Гурский Юрий Анатольевич

Освобождение блокировки int pthread_rwlock_unlock(pthread_rwlock_t* rwl);Функция освобождает захваченный любым образом объект блокировки чтения/записи. Если объект был захвачен в режиме множественного использования (блокировки по чтению), то количество его освобождений должно равняться


21.6.1. Команды free и df — информация о системных ресурсах

Из книги Разработка ядра Linux автора Лав Роберт

21.6.1. Команды free и df— информация о системных ресурсах Команда free выводит информацию об использовании оперативной и виртуальной памяти, а df — об использовании дискового пространства. Из рис. 21.5 видно, что в системе установлено всего 512 Мбайт ОЗУ, из них почти все занято. На


5.1.5. Контроль и освобождение совместно используемой памяти

Из книги Социальные сети. ВКонтакте, Facebook и другие… автора Леонтьев Виталий Петрович

5.1.5. Контроль и освобождение совместно используемой памяти Функция shmctl() возвращает информацию о совместно используемом сегменте и способна модифицировать его. Первым параметром является идентификатор сегмента.Чтобы получить информацию о сегменте, укажите в качестве


12.3. Free Transform (Произвольное трансформирование)

Из книги Священные войны мира FOSS автора Федорчук Алексей Викторович

12.3. Free Transform (Произвольное трансформирование) Если предыдущие инструменты изменения размеров предназначены для всего изображения, то Free Transform (Произвольное трансформирование) позволяет изменять не только размеры, но и пропорции, угол поворота для выделенного объекта или


Fera Free For Facebook

Из книги автора

Fera Free For Facebook По дизайну эта «альтернативка» уделывает официальный клиент, как павлин инфузорию-туфельку. Все удобно, все разнесено по функциональным вкладкам… И вместо скучной «простыни» линейного текст мы видим грамотную верстку. Почти журнал получается, хотя и не до