Память и указатели

Мне нужна помощь с размышлениями о задаче.

Моя задача - создать одну область памяти

void *memory = malloc(320);

и затем использовать указатели для хранения текстов в этом месте хранения: мы хотим разделить эту область на блоки данных по 32 байта, то есть мы можем сохранить: 320/32 = 10 блоков данных по 32 байта. В одном блоке данных я могу хранить (1 ASCSII символ = 1 байт) 32 символа.

У меня есть растровое изображение длиной 10, где каждый бит указывает, используется ли блок данных (1) или нет (0).

Но что, если я хочу сохранить текст длиной 60 символов? Тогда мне нужно 2 блока данных (2 х 32 байта). Битовая карта показывает, что блоки данных 2 и 6 свободны, 1 и 6 не расположены рядом. Как мне этого добиться?

struct  data {
    char * text;
};

typedef struct data d;

d->text = ???

6 ответов

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

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

Чтобы исправить проблему в C:
Вы ничего не можете сделать, потому что эти указатели в памяти не позволяют вам перетасовать все. Кто-то еще упомянул систему друзей, но есть и другие, но некоторые из них простые. Многие из них основаны на наличии предустановленных "больших порций" и "маленьких порций" и разрешении только небольших запросов на мелкие порции и т. Д.... но это все, чтобы перестать приходить к проблеме в первую очередь, как только вы окажетесь там, вы либо отрицаете запрос памяти или расширение пула.

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

Есть методы, чтобы минимизировать фрагментацию. Одним из популярных способов является выделение памяти для друзей: http://en.wikipedia.org/wiki/Buddy_memory_allocation

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

Некоторые мысли от макушки головы:

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

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

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

Вы можете получить байт из каждого из 10 32-байтовых пространств и использовать этот байт как указатель на продолжение строки. На самом деле это был бы связанный список, и вы могли бы сделать его дважды связанным списком, имея прямые и обратные индексы.

Другие вопросы по тегам