Распределитель памяти в C - как использовать пространство sbrk () - PullRequest
4 голосов
/ 26 марта 2011

Я пишу реализацию malloc и хотел знать, может ли кто-нибудь помочь мне с этой проблемой.

В принципе, я хотел бы повторно использовать память после ее выделения с помощью sbrk () и убедившись, чточто память свободна.

Итак, представьте, что моя память такая:

|------------------------------|

... и я делаю некоторые выделения.Когда я выделяю память, у каждого бита есть заголовок (h) и данные (d).

|hddddddhddd---hdd--hddd-------|

Теперь у меня есть эти дыры, и если я хочу использовать, скажем, первый пробел в моей диаграмме, как мне настроить его так, чтобы у него также были голова (h) и тело (dd)?

Я дошел до того, что теперь у меня есть указатель на область памяти Iхочу.В C его указывает указатель.Указатель имеет пользовательский тип, где «meta» - это структура, которую я определил.Так что теперь у меня есть

metaStruct * mypointer = the memory address.

Но когда я пытаюсь сделать

mypointer->size = 30;

или

mypointer->buddy = 1;

, я получаю ошибку сегмента.

вопрос: как мне настроить так, чтобы адрес памяти, выделенный через sbrk (), имел форму моей структуры?Очевидно, я не могу просто пойти myPointer = malloc (sizeof (metaStruct)), потому что я пишу сам malloc.Мне также не интересно, чтобы sbrk () занимал больше места, а скорее использовал существующее пространство, на которое я указываю (я хочу игнорировать его ненужные данные и использовать пространство).

Как сделатьЯ собираюсь сделать это?

1 Ответ

4 голосов
/ 26 марта 2011

Насколько я знаю, p = sbrk (n) увеличивает доступное адресное пространство (как минимум) n байтов и возвращает базовый адрес новой выделенной области в "p".Итак, теперь у вас есть блок памяти, начинающийся с «p» и длиной n байтов (вероятно, больше, чем n, это зависит от системы).

Итак, я полагаю, что ваш «metaStruct» содержит поле «size», поле «следующая свободная область» и поле «данные»,

metaStruct * m ;
p=sbrk(sizeof(metaStruct)+ data_size);
m = (metaStruct *)p;
m->size = data_size;
m->next = NULL;
memcpy(m->data, ...,data_size);

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

...