Я реализую класс типа пула памяти. Один из методов выделяет B байтов памяти и возвращает на него указатель void, при этом внутренне обрабатывая буферы и перемещая старую память, чтобы гарантировать, что вся память, управляемая объектом во время его существования, является смежной (аналогично тому, как std :: vector будет иметь предварительно выделенный буфер и выделить дополнительное пространство, когда буфер закончится, копируя информацию из старого буфера в новый, чтобы гарантировать непрерывность всей памяти). У меня вопрос: как обеспечить непрерывность всей выделенной памяти? Если я хочу перейти от объекта к объекту вручную, используя
static_cast<desired_type*>(buffer_pointer + N)
Этот метод, естественно, потерпит неудачу, если местоположение объекта смещено на некоторую величину, которая не является просто суммой размеров предыдущих объектов. Я новичок в написании пользовательских пулов памяти, поэтому мне просто интересно, как мне либо убедиться, что выделенная память не фрагментирована, либо получить доступ к местоположению нового фрагмента, чтобы я мог вручную индексировать через блок malloc () - ed объем памяти? Спасибо.
Напишите свой собственный распределитель?
кажется, что вам нужно управлять всей информацией, связанной с объектами (размер, местоположение ...)
@duong_dajgja Да, класс отслеживает количество уже использованных байтов и максимальную емкость байтов. Что я не знаю, так это отслеживать местоположение. Метод распределения возвращает кортеж указателя на начало непрерывного блока памяти (в случае, если он изменился по сравнению с предыдущим распределением из-за переполнения буфера), и указатель на начало нового местоположения. Однако, когда к нему добавляется новая память, я хочу иметь возможность брать начальный указатель и увеличивать его по размеру, чтобы получить, где заканчивается каждый объект и начинается другой, поэтому я хочу знать, как я могу проверить непрерывность
@ Jean-FrançoisFabre Да, метод выделяет буфер из одного malloc до тех пор, пока буфер не переполнится (N + 1 байт запрашивается из буфера размера N). В случае переполнения класс перемещает данные в новый буфер достаточного размера. Я хочу иметь возможность извлекать позицию каждого объекта только по размеру каждого объекта и начальной позиции, что должно быть простым - просто добавьте кумулятивные предыдущие размеры в начало. Однако не уверен, работает ли это для фрагментированной памяти, поэтому есть ли способ проверить фрагментацию, или это не проблема с одним буфером malloc?
@SaswatMishra У вас должна быть карта, которая сопоставляет некоторый идентификатор объекта с некоторым смещением в пуле? По карте можно проверить, расположены ли объекты смежно, верно?
@duong_dajgja Это похоже на то, что есть у меня, и это отлично работает до тех пор, пока не произойдет сдвиг буфера, о котором я упоминал, когда все адреса будут сдвинуты. Метод возвращает новую начальную позицию, и я должен иметь возможность получить новые позиции, перейдя (begin + sizeof (previous_objects)), но я не уверен, работает ли этот метод для фрагментированной памяти, что может произойти при выделении больших блоки памяти.
@ P.W да, этот инструмент должен помочь гарантировать, что память, назначенная для другого класса, который я использую, правильно выровнена, а также непрерывна. По сути, распределитель.
Мне кажется, это слишком широко для сайта, но обратите внимание, что типичная виртуальная машина Java делает все это довольно хорошо. (Я также не уверен, что вы можете сделать это на переносимом C или C++). Почему бы не изучить тот, который написан на C или C++?
Что вы имеете в виду под фрагментированной памятью? Malloc всегда возвращает непрерывный блок памяти. Вы имеете в виду, что память фрагментирована после некоторого использования или возвращенный malloc памяти фрагментирован?





Если я понимаю ваш вопрос, вы спрашиваете, можно ли иметь несколько вызовов malloc для возврата непрерывной памяти.
Ответ: нет, память не будет смежной между несколькими маллоками, поскольку большинство менеджеров памяти будут размещать данные заголовка / хвоста вокруг выделенной памяти как для своего собственного управления, так и для размещения маркеров защиты по краям для обнаружения переполнения - детали в значительной степени зависят от реализации .
для вашего собственного управления памятью вам нужно выделить достаточно большой блок с помощью malloc, а затем разделить его и самостоятельно управлять внутренними компонентами.
Вы можете посмотреть на этот проект на github как на пример необходимого управления: https://github.com/bcorriveau/memblock
единственное решение - выделить блок не замужем с помощью
mallocилиnewи управлять им вручную. Или используйте предварительно выделенныйvector.