Как работает free в си

от admin

Динамическая память

При создании массива с фиксированными размерами под него выделяется определенная память. Например, пусть у нас будет массив с пятью элементами:

Для такого массива выделяется память 5 * 8 (размер типа double) = 40 байт. Таким образом, мы точно знаем, сколько в массиве элементов и сколько он занимает памяти. Однако это не всегда удобно. Иногда бывает необходимо, чтобы количество элементов и соответственно размер выделяемой памяти для массива определялись динамически в зависимости от некоторых условий. Например, пользователь сам может вводить размер массива. И в этом случае для создания массива мы можем использовать динамическое выделение памяти.

Для управления динамическим выделением памяти используется ряд функций, которые определены в заголовочном файле stdlib.h :

malloc() . Имеет прототип

Выделяет память длиной в s байт и возвращает указатель на начало выделенной памяти. В случае неудачного выполнения возвращает NULL

calloc() . Имеет прототип

Выделяет память для n элементов по m байт каждый и возвращает указатель на начало выделенной памяти. В случае неудачного выполнения возвращает NULL

realloc() . Имеет прототип

Изменяет размер ранее выделенного блока памяти, на начало которого указывает указатель bl, до размера в ns байт. Если указатель bl имеет значение NULL , то есть память не выделялась, то действие функции аналогично действию malloc

free() . Имеет прототип

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

malloc

Функция malloc() выделяет память длиной для определенного количества байт и возвращает указатель на начало выделенной памяти. Через полученный указатель мы можем помещать данные в выделенную память. Рассмотрим простой пример:

Здесь с помощью функции malloc выделяется память для одного объекта int . Чтобы узнать, сколько байтов надо выделить, передаем в функцию malloc размер типа int на текущей и в результате получаем указатель ptr , который указывает на выделенную память

То есть поскольку int на большинстве архитектур занимает 4 байта, то в большинстве случаев будет выделяться память объемом в 4 байта. Стоит отметить, что мы также могли бы получить размер через разыменование указателя:

Для универсальности возвращаемого значения в качестве результата функция malloc() (как и calloc() и realloc() ) возвращает указатель типа void * . Но в нашем случае создается массив типа int, для управления которым используется указатель типа int * , поэтому выполняется неявное приведение результата функции malloc к типу int * .

Далее через этот указатель с помощью операции разыменования помещаем в выделенный участок памяти число 24:

В дальнейшем, используя указатель, можно получить значение из выделенного участка памяти:

После завершения работы освобождаем память, передавая указатель в функцию free() :

Стоит отметить, что теоретически мы можем столкнуться с тем, что функции malloc() не удастся выделить требуемую память, и тогда она возвратит NULL. Чтобы избежать подобной ситуации перед использованием указателя мы можем проверять его на значение NULL:

Немотря на освобождение памяти с помощью функции free() указатель сохраняет свой адрес, и теоретически мы можем обращаться к памяти по данному указателю. Однако полученные значения уже будут неопределенными и недетеминированными. Поэтому некоторые советуют после освобождения памяти также устанавливать для указателя значение NULL :

Выделение памяти для массива

Подобным образом можно выделять память и под набор объектов. Например, выделим память для массива из 4-х чисел int:

Выделение памяти для структуры

Аналогичным образом можно выделять память для одной или набора структур:

calloc

Функция calloc() имеет прототип

Она выделяет память для n элементов по m байт каждый и возвращает указатель на начало выделенной памяти. В случае неудачного выполнения возвращает NULL

В отличие от функции malloc() она инициализирует все выделенные байты памяти нулями. Например, выделим память для одного объекта int :

Подобным образом можно выделить память и для других объектов. Например, выделим память для массива из 4-х объектов int :

realloc

Функция realloc() позволяет изменить размер памяти, ранее выделенной с помощью функций malloc() b calloc() . Имеет прототип

Первый параметр представляет указатель на ранее выделенный блок памяти. А второй параметр представляет новый размер блока памяти в байтах.

Если указатель bl имеет значение NULL , то есть память не выделялась, то действие функции аналогично действию malloc

Читать:
Какую задачу решает локально чувствительное хеширование документов

Рассмотрим небольшой пример:

Здесь сначала выделяем память для одного объекта int с помощью функции malloc.

Если память успешно выделена, то выводим на консоль адрес и размер выделенного блока памяти. Затем с помощью функции realloc расширяем память до 4 объектов int

Если увеличение памяти прошло успешно, то заново выводим данные на консоль и освобождаем память по новому указателю. Если увеличение памяти прошло не удачно, то освобождаем память но старому указателю.

Консольный вывод в моем случае

Стоит отметить, что нам необязательно создавать новый указатель, мы можем присвоить значение старому указателю:

Как работает free в си

Deallocates the space previously allocated by malloc() , calloc() , aligned_alloc() , (since C11) or realloc() .

If ptr is a null pointer, the function does nothing.

The behavior is undefined if the value of ptr does not equal a value returned earlier by malloc() , calloc() , realloc() , or aligned_alloc() (since C11) .

The behavior is undefined if the memory area referred to by ptr has already been deallocated, that is, free() , free_sized() , free_aligned_sized() (since C23) , or realloc() has already been called with ptr as the argument and no calls to malloc() , calloc() , realloc() , or aligned_alloc() (since C11) resulted in a pointer equal to ptr afterwards.

The behavior is undefined if after free() returns, an access is made through the pointer ptr (unless another allocation function happened to result in a pointer value equal to ptr ).

free is thread-safe: it behaves as though only accessing the memory locations visible through its argument, and not any static storage.

A call to free that deallocates a region of memory synchronizes-with a call to any subsequent allocation function that allocates the same or a part of the same region of memory. This synchronization occurs after any access to the memory by the deallocating function and before any access to the memory by the allocation function. There is a single total order of all allocation and deallocation functions operating on each particular region of memory.

Contents

[edit] Parameters

ptr pointer to the memory to deallocate

[edit] Return value

[edit] Notes

The function accepts (and does nothing with) the null pointer to reduce the amount of special-casing. Whether allocation succeeds or not, the pointer returned by an allocation function can be passed to free() .

Как работает free в си

When memory blocks are allotted by calloc(), malloc(), or realloc() functions, the C library function free() is used to deallocate or release the memory blocks to reduce their wastage.

free() function in C should only be used either for the pointers pointing to the memory allocated using malloc() or for a NULL pointer. free() function only frees the memory from the heap and it does not call the destructor. To destroy the allocated memory and call the destructor we can use the delete() operator in C.

Syntax to Use free() function in C

Here, ptr is the memory block that needs to be freed or deallocated.

For example, program 1 demonstrates how to use free() with calloc() in C and program 2 demonstrates how to use free() with malloc() in C.

Функция free

Функция free освобождает место в памяти. Блок памяти, ранее выделенный с помощью вызова malloc , calloc или realloc освобождается. То есть освобожденная память может дальше использоваться программами или ОС.

Обратите внимание, что эта функция оставляет значение ptr неизменным, следовательно, он по-прежнему указывает на тот же блок памяти, а не на нулевой указатель.

Параметры:

  • ptrmem
    Указатель на блок памяти, ранее выделенный функциями malloc , calloc или realloc , которую необходимо высвободить. Если в качестве аргумента передается нулевой указатель, никаких действий не происходит.

Возвращаемое значение

Функция не имеет возвращаемое значение.

Пример: исходный код программы

Пример работы программы

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

Похожие статьи