Книга: Основы программирования в Linux

Другие функции распределения памяти

Другие функции распределения памяти

Две другие функции распределения или выделения памяти calloc и realloc применяются не так часто, как malloc и free.

Далее приведены их прототипы:

#include <stdlib.h>
void *calloc(size_t number_of_elements, size_t element_size);
void *realloc(void *existing_memozy, size_t new_size);

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

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

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

my_ptr = malloc(BLOCK_SIZE);
...
my_ptr = realloc(my_ptr, BLOCK_SIZE * 10);

Если realloc завершится аварийно, она вернет пустой указатель; переменная my_ptr будет указывать в никуда и к первоначальной области памяти, выделенной функцией malloc, больше нельзя будет обратиться с помощью указателя my_ptr. Следовательно, было бы полезно сначала запросить новый блок памяти с помощью malloc, а затем скопировать данные из старого блока памяти в новый блок с помощью функции memcpy и освободить старый блок памяти вызовом free. При возникновении ошибки это позволит приложению сохранить доступ к данным, хранящимся в первоначальном блоке памяти, возможно, на время организации корректного завершения программы.

Оглавление книги


Генерация: 2.432. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз