Выравнивание указателей после переопределения памяти - PullRequest
0 голосов
/ 08 ноября 2018

У меня есть пул памяти установленного размера и разбит на сегменты заданного размера. Когда я удаляю некоторые данные, они помечают сегменты, которые использовались данными, как свободные. В следующий раз, когда я пытаюсь выделить память, но у меня нет места, я перестраиваю память, сдвигая все данные вниз (например, первые 2 сегмента очищаются, все данные перемещаются вниз на 2 блока). Это все работает нормально, но моя проблема в том, что мои указатели на эти данные не меняются, и я не уверен, как мне это сделать.

Я выделяю память из своего пула, возвращая пустое пространство * в память, допустим, что мой пул имеет размер 2 * sizeof (Data).

Data* poolTest = new(pool->GetMemory(sizeof(Data))) Data(5, 5, 5);

Таким образом, пул не имеет ссылки на указатель poolTest.

Так что теперь, если я сделаю это:

pool->Free(poolTest);
Data* poolTest2 = new(pool->GetMemory(sizeof(Data))) Data(4, 5, 5);
Data* poolTest3 = new(pool->GetMemory(sizeof(Data))) Data(3, 5, 5);

Создание poolTest3 инициирует перераспределение памяти, и теперь poolTest2 указывает на тот же адрес, что и poolTest3, а poolTest1 указывает на адрес, на который должен указывать poolTest2.

Возможно, я просто что-то упустил, или моя структура испорчена, но я действительно застрял в этом.

1 Ответ

0 голосов
/ 08 ноября 2018

Чтобы перефразировать ваш вопрос:

Я хочу переместить данные в память, чтобы освободить место для новых выделений. Как убедиться, что существующие указатели все еще указывают на правильные места?

Вы не сможете , если только вы не будете отслеживать все указатели, скажем, используя массив, и вместо того, чтобы обращаться к вашим данным, как это:

*direct_ptr

Теперь вы должны сделать это:

*ptr_map[indirect_ptr]

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

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

Это может сэкономить немного места, но совершенно неэффективно для компьютера и грязно для программиста.

Если вы хотите сделать свое собственное управление памятью, обязательно проверьте:

https://en.wikipedia.org/wiki/Buddy_memory_allocation

https://en.wikipedia.org/wiki/Slab_allocation

И хороший обзор существующих техник:

http://pages.cs.wisc.edu/~remzi/OSTEP/vm-freespace.pdf

...