Освобождение частей динамически распределенных блоков? - PullRequest
1 голос
/ 01 марта 2012

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

Например:

char* a = malloc (40);
//b points to the split second half of the block, or to NULL if it's beyond the end
//a points to a area of 10 bytes
b = partial_free (a+10, /*size*/ 10) 

Мысли о том, почему это мудро / неразумно / сложно? Способы сделать это?

Мне кажется, это может быть полезно.

Спасибо!

===== ===== редактировать после некоторых исследований кажется, что распределитель bootmem для ядра linux допускает нечто похожее на эту операцию с вызовом bootmem_free. Итак, мне любопытно - почему распределитель bootmem позволяет это, а ANSI C - нет?

Ответы [ 3 ]

3 голосов
/ 01 марта 2012

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

Из стандарта c:

7.22.3.5 Функция realloc

#include <stdlib.h>
void *realloc(void *ptr, size_t size);

Функция realloc освобождает старый объектуказывает на ptr и возвращает указатель на новый объект, размер которого определяется размером.Содержимое нового объекта должно быть таким же, как и у старого объекта до освобождения, до меньшего из нового и старого размеров.Любые байты в новом объекте, превышающие размер старого объекта, имеют неопределенные значения.

1 голос
/ 01 марта 2012

Во-первых, я не могу вспомнить ни одной ситуации, когда вам, вероятно, понадобится такая вещь (когда существует realloc для увеличения / уменьшения памяти, как упомянуто в ответах).

Я хотел бы добавитьеще одна вещь.В любых реализациях, которые я видел в подсистеме malloc (которую, я признаю, не так много), malloc и free реализованы так, чтобы зависеть от того, что называется префиксным байтом (байтами).Таким образом, независимо от того, какой адрес вам возвращает malloc, внутренняя подсистема malloc будет выделять дополнительные байты памяти перед возвращенным вам адресом, чтобы хранить информацию о проверке работоспособности, которая включает количество выделенных байтов и, возможно, какую политику выделения вы используете.(если ваша ОС поддерживает несколько политик выделения памяти) и т. д. Когда вы говорите что-то вроде free (x байтов), подсистема malloc возвращается к просмотру байта префикса для проверки работоспособности, и только если она находит префикс на месте, освобождаетсяуспешно получилось.Следовательно, он не позволит вам освободить некоторое количество блоков, начинающихся между ними.

1 голос
/ 01 марта 2012

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

Теперь, если вы выделили немного памяти:

char * tmp = malloc(2048); 

и намереваетесь освободить первую 1 КБ памяти, вы можете сделать:

tmp = realloc(foo, 2048-1024);

Однако проблема в этом случае заключается в том, что вы не можете быть уверенными , что tmp останется неизменным.Так как функция может просто освободить всю память 2K и переместить ее в другое место.

Теперь я не уверен насчет точной реализации realloc , но, насколько я понимаю, код:

myptr = malloc( x - y );

на самом деле malloc sa новая памятьбуфер размером x-y, затем он копирует байтов, которые соответствуют, используя memcpy и, наконец, free s исходной выделенной памяти.

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

...