Класс std::vector
автоматически управляет внутренней памятью. Он будет расширяться, чтобы вмещать столько элементов, сколько вы поместите в него, но в целом он не будет уменьшаться сам по себе при удалении элементов (хотя, конечно, он освобождает память при разрушении).
У std::vector
есть два соответствующих понятия «размер». Во-первых, это «зарезервированный» размер, который представляет собой объем памяти, выделенный системой для хранения векторных элементов. Второй - это «используемый» размер, который определяет, сколько элементов логически находится в векторе. Понятно, что зарезервированный размер должен быть не меньше используемого размера. Вы можете определить используемый размер с помощью метода size()
(который, я уверен, вы уже знаете), а зарезервированный размер - с помощью метода capacity()
.
Обычно, когда используемые и зарезервированные размеры совпадают, и вы пытаетесь вставить новый элемент, вектор выделит новый внутренний буфер, в два раза превышающий предыдущий зарезервированный размер, и скопирует все существующие элементы в этот буфер. Это прозрачно для вас, за исключением того, что оно сделает недействительными любые итераторы, которые вы держите. Как я уже отмечал ранее, AFAIK, большинство реализаций STL никогда не уменьшают зарезервированный размер в ответ на удаление.
К сожалению, хотя вы можете заставить вектор увеличить его зарезервированный размер, используя метод reserve()
, это не работает для уменьшения зарезервированной емкости. Насколько я могу судить, вам лучше всего сделать следующее:
std::vector<Bullet>(myVector).swap(myVector);
Что это будет делать, это создать временный вектор, который является копией исходного вектора (но с минимально необходимой емкостью), а затем поменять местами внутренние буферы двух векторов. Это приведет к тому, что ваш исходный вектор будет иметь те же данные, но потенциально меньший зарезервированный размер.
Теперь, поскольку создание этой временной копии является относительно дорогой операцией (т. Е. Она занимает намного больше процессорного времени, чем обычные операции чтения / вставки / удаления), вы не хотите делать это каждый раз, когда стираете элемент. По той же причине, поэтому вектор удваивает свой зарезервированный размер, а не увеличивает его на 1, когда вам нужно превысить существующий размер. Поэтому я бы порекомендовал, чтобы после того, как вы удалили относительно большое количество элементов и знаете, что в ближайшее время не добавите их еще больше, выполните «трюк» подкачки, чтобы уменьшить емкость.
Наконец, вы также можете рассмотреть возможность использования для этого чего-то отличного от std::vector
. Стирание элементов из середины вектора, что, по-видимому, вы часто делаете, является медленной операцией по сравнению со многими другими типами структур данных (поскольку вектор должен скопировать все последующие элементы обратно в один слот, чтобы заполнить дыру) , Какая структура данных лучше всего подходит для ваших целей, зависит от того, что еще вы делаете с данными.