Как распределитель C ++ должен обрабатывать свою выделенную память, когда она уничтожается / копируется / перемещается?

В настоящее время я пишу распределитель, который должен использоваться стандартными структурами данных C ++, т.е. он реализует Концепция аллокатора.

Распределитель довольно прост: он выделяет блоки из x объектов и всегда передает следующий объект, если текущий блок не заполнен, в противном случае он выделяет новый блок.

Теперь мой вопрос: как обрабатывать эти куски, когда распределитель уничтожен / скопирован / перемещен? Концепция распределителя ничего не говорит о том, что должно произойти в этих случаях.

Вот мои мысли:

  • Уничтожение: распределитель может уничтожить все свои блоки. Но тогда ни один объект, который использует какой-либо из выделенных объектов, не может пережить распределитель.
  • Копирование: самая простая идея - скопировать фрагменты. Но если подумать, это не имеет смысла: никто не знает адреса объектов в скопированных фрагментах, поэтому они просто копируются без какой-либо выгоды. Может быть, скопированный распределитель должен начинаться с пустого списка кусков.
  • Перемещение: фрагменты следует переместить в новый распределитель. Старый должен остаться с пустым списком кусков.

Мои предположения верны? Если нет, то почему и где это определяется?


person gexicide    schedule 10.11.2014    source источник


Ответы (1)


Распределители обычно представляют собой легкие объекты, которые можно копировать и уничтожать, например в стандартных контейнерных классах. Следовательно, они не должны сами выполнять тяжелое управление памятью, а должны передавать ее какому-нибудь более постоянному объекту диспетчера памяти. Если вы это сделаете, время жизни фрагментов памяти будет зависеть не от времени жизни распределителя, а от времени жизни объекта диспетчера памяти. Следовательно, жизненные мысли должны применяться к обоим типам объектов:

Распределитель (короткое время жизни):

  • Копирование / перемещение: скопируйте ссылку в диспетчер памяти.
  • Уничтожение: либо ничего не делает (внешнее управление временем жизни диспетчера памяти), либо, возможно, уничтожает диспетчер памяти, например у каждого распределителя есть shared_ptr для диспетчера памяти

Диспетчер памяти (долгий срок службы):

  • Копирование нужно запретить, нет смысла дублировать диспетчер и его управляемое хранилище
  • Переезд можно разрешить, но в этом нет особого смысла. Менеджер памяти может даже быть одноэлементным классом, то есть одним фиксированным экземпляром, который не нужно перемещать.
  • Уничтожение должно включать уничтожение управляемой памяти, поскольку ни один другой объект не знает, как освободить управляемую память.
person Arne Mertz    schedule 10.11.2014