2010-10-14 2 views
5

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

Моя задача состоит в том, чтобы создать площадь одной памяти

void *memory = malloc(320); 

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

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

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

struct data { 
    char * text; 
}; 

typedef struct data d; 

d->text = ??? 
+8

Если не существует двух смежных свободных блоков, вы не можете удовлетворить запрос для 60-байтовой строки. Вы только что обнаружили «фрагментацию памяти»: http://en.wikipedia.org/wiki/Memory_fragmentation –

+0

Таким образом, вашими единственными параметрами были бы дефрагментация (которая требует от людей не удерживать указатели) или выделять больше памяти. – EboMike

+1

или для создания цепей – pm100

ответ

4

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

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

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

+0

Хорошо. Но так или иначе сделать это на C с указателями? Это задача, которую я должен выяснить. – user265767

0

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

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

0

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

0

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

0

Некоторые мысли с верхней части моей головы:

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

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

+0

Или каждый блок char a [32], сообщение struct содержит массив, который указывает на data_blocks, тогда я могу разделить строку на блоки и добавить номер блока в массив? – user265767

0

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