сокращение вектора - PullRequest
       12

сокращение вектора

7 голосов
/ 25 февраля 2009

У меня проблема с двигателем местности (использующим DirectX).

Я использую вектор для хранения вершин блока детализации. Когда блок увеличивается в деталях, то и вектор увеличивается.

НО, когда блок уменьшает свою детализацию, вектор не уменьшается в размере.

Итак, мой вопрос: есть ли способ уменьшить размер вектора? Я попробовал это:

vertexvector.reserve(16);

Ответы [ 4 ]

27 голосов
/ 25 февраля 2009

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

vector<vertex>(a).swap(a);

Он известен как идиома "сжимайся, чтобы соответствовать". Кстати, в следующей версии C ++ есть функция-член shrink_to_fit () для std :: vector.

8 голосов
/ 25 февраля 2009

Обычный трюк - поменять местами пустой вектор:

vector<vertex>(vertexvector.begin(), vertexvector.end()).swap(vertexvector);
6 голосов
/ 25 февраля 2009

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

  1. Запросить у распределителя новое, меньшее место в памяти,
  2. Скопируйте содержимое из старого местоположения и
  3. Скажите распределителю освободить старую ячейку памяти.

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

Если у вас было очень большое изменение требуемого размера, и вы знаете , что вы не захотите, чтобы этот вектор снова расширялся (принципал местности предполагает, что вы это сделаете, но, конечно, исключения), то вы можете использовать предложенную литва операцию свопа, чтобы явно уменьшить ваш вектор:

vector<vertex>(a).swap(a);
0 голосов
/ 24 октября 2014

Для этого есть функция-член shrink_to_fit. Он более эффективен, чем большинство других методов, поскольку он выделяет новую память и копирует ее только в случае необходимости. Детали обсуждаются здесь, Является ли shrink_to_fit правильным способом уменьшения емкости `std :: vector` до ее размера?

Если вы не возражаете против использования функций выделения libc, realloc еще более эффективен, он не будет копировать данные при сжатии, просто пометьте дополнительную память как свободную, и если вы увеличите объем памяти и после нее будет свободная память пометьте нужную память как использованную и не копируйте. Однако будьте осторожны: вы переходите из шаблонов C ++ stl в пустые указатели C и должны понимать, как работают указатели и управление памятью, и многие считают его источником ошибок и утечек памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...