2009-08-07 6 views
9

Я использую std::deque для хранения довольно большого количества объектов. Если я удалю кучу этих объектов, мне кажется, что его использование памяти не уменьшается, подобно std :: vector.Как выпустить память из std :: deque?

Есть ли способ уменьшить его? Я знаю, что в векторе вы должны использовать «своп-трюк», который, как я полагаю, тоже будет работать здесь, но я бы предпочел избежать этого, поскольку для этого потребуется скопировать все элементы, оставшиеся в контейнере (и, следовательно, достаточно памяти для хранения каждого объекта дважды). Я не знаком с реализацией deque, но мое понимание этого заключается в том, что можно было бы достичь такой вещи без большого количества копий (тогда как с вектором это явно не было).

Я использую STL VC++ (Dinkumware), если это имеет значение.

+2

Установили ли вы, что ваша реализация deque еще не освобождает блоки памяти, как только достаточно элементов для удаления их? Или вы действительно хотите выжать последние несколько байтов, перераспределяя блок на каждом конце? –

+0

Я так думаю, довольно грубо и готово: я добавляю 100 000 предметов -> Использование памяти - 90 МБ. Я добавляю еще 100 000 -> использование памяти ~ 170 МБ. Я удаляю 100 000 элементов -> использование памяти по-прежнему ~ 170 МБ. Добавьте еще 100 000 -> еще 170. Я предполагаю, что 100 000 предметов более чем достаточно, чтобы у него были пустые блоки, которые он бы освободил, если бы собирался. – Peter

+5

Использование памяти в процессе или использование памяти в коллекции? Просто потому, что коллекция освобождает память, это не значит, что она возвращается к ОС, поэтому попробуйте выделить 80MB массива символов после удаления элементов и посмотреть, будет ли использование 250MB, или останется в 170. Извините, если вы уже знаете все это вещи и учли это - миллионы не будут. –

ответ

14

Невозможно сделать это прямо в std :: deque. Однако это легко сделать с помощью временного (что в основном происходит в std :: vector, когда вы уменьшаете его емкость).

Здесь good article on std::deque, сравнивая его с std :: vector. На самом дне показан чистый способ поменять и сжать вектор, который работает одинаково с deque.

+0

Спасибо. Я подозревал, что не может быть никакого способа сделать это, но похоже, что это должно быть возможно ... Я объяснил в вопросе, почему я не хочу использовать вещь свопа в этом случае, но, возможно, я буду должны смотреть в нее независимо. – Peter

+0

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

+0

Обменная вещь только когда-либо заменяет внутренние указатели вектора, а не сами элементы. – Karu

4

Размер памяти дека может или не уменьшится. Когда и Как это происходит, зависит от реализации. К сожалению, у вас нет большого ручного контроля над этим, так как у deques нет даже емкости() или reserve().

Я бы предложил swap(), если вы действительно обнаруживаете, что освобождение памяти не выполняется в удобное для вас время.

Интимное знание управления Deque памяти, вероятно, может быть получена с сайта Dikum (это текущая реализация, верно?)

1

станд :: Deque будет возвращать память его распределителем. Часто этот распределитель не возвращает память в ОС. В таких случаях кажется, что память не «освобождена». Хорошие детекторы утечки памяти будут удовлетворены, как только память вернется в распределитель, и поймите, что не вся память выпущена free().

3

Как добавил информацию к этому:

В C++ 0x/C++, 11, Deque (и несколько других контейнеров) имеет новую функцию под названием «shrink_to_fit», который будет удалить избыточные элементы, и в основном выравнивания потенциала() == size()

+0

capacity() все еще может быть выше, чем size() после shrink_to_fit() - это необязательный запрос; 'void shrink_to_fit() {}' на самом деле является совершенно законной реализацией. Но даже при хорошей реализации capacity() может быть выше, чем size(), например, если в контейнере слишком мало элементов, все равно стоит выделить больше памяти. (Подумайте о пустых контейнерах.) – Lrdx