2009-07-20 3 views
23

Стандарт C++, по-видимому, не дает никаких пояснений относительно побочных эффектов по емкости либо resize(n), с n < size(), либо clear().std :: vector resize down

Это делает заявление о амортизированной стоимости push_back и pop_back - O (1)

Я могу представить себе реализацию, которая делает обычный вид емкости изменяется ала КСПС алгоритмов (например, двойные при увеличении, вдвое сократить время уменьшение size to < capacity()/4). (Cormen Lieserson Rivest Stein)

У кого-нибудь есть ссылка на любые ограничения по реализации?

ответ

34

Вызов resize() с меньшим размером не влияет на емкость vector. Это не освободит память.

Стандартная идиома для освобождения памяти от vector является swap() его с пустой временной vector: std::vector<T>().swap(vec);. Если вы хотите изменить размер вниз, вам нужно будет скопировать исходный вектор в новый локальный временный вектор и затем поменять полученный вектор на ваш оригинал.

Обновлено: C++ 11 добавлена ​​функция члена shrink_to_fit() для этой цели, это необязательный запрос, чтобы уменьшить capacity() к size().

+0

Способ, которым я его читал, он спрашивает о влиянии на использование памяти - он конкретно задает вопрос о том, какое влияние на емкость оказывает изменение размера. Стандарт не определяет результат в этом случае, но единственная причина, по которой я могу думать, - это желание освободить неиспользованную память. Обмен с временным трюком - это идиоматический способ достижения этого. – mattnewport

+2

В стандарте указан результат, не указывая уменьшение емкости() для этих операций. Поэтому он не может уменьшиться. – MSalters

+2

Есть некоторые среды, где запрещено выделять или освобождать память после начальной фазы «строительства». Векторы можно использовать в этой среде, если можно быть уверенным, что они не пытаются выделять или освобождать память во время операций. Поэтому этот вопрос имеет значение в этой ситуации (что привело меня сюда). – meowsqueak

21

На самом деле, стандарт делает указать, что должно произойти:

Это из vector, но тема та же для всех контейнеров (list, deque и т.д ...)

23,2 .4.2 вектор емкости [lib.vector.capacity]

void resize(size_type sz, T c = T());

6) Эффекты:

if (sz > size()) 
    insert(end(), sz-size(), c); 
else if (sz < size()) 
    erase(begin()+sz, end()); 
else 
    ; //do nothing 

То есть: Если размер, указанный в resize меньше, чем число элементов, эти элементы будут удалены из контейнера. Что касается capacity(), это зависит от того, что делает erase().

Я не могу найти его в стандарте, но я уверен, что clear() определяется как:

void clear() 
{ 
    erase(begin(), end()); 
} 

Таким образом, эффекты clear() имеет на capacity() также связана с эффектами erase() имеет на него. В соответствии со стандартом:

23.2.4.3 векторные модификаторы [lib.vector.модификаторы]

iterator erase(iterator position); 
iterator erase(iterator first, iterator last); 

4) Сложность: Деструктор Т называется число раз, равное числу элементов стертых ....

Это означает, что элементы будет разрушена, но память останется неповрежденной. erase() не влияет на мощность, поэтому resize() и clear() также не действуют.

+0

Возможно, слишком много стандартного? Я согласен с вашим заключением, но многие из них на самом деле не затрагивают этот вопрос. – 2009-07-20 20:48:57

+0

Согласовано. Я немного подрезал его. :) – GManNickG

+0

Вы обрезали его слишком много, абзац «Эффекты» предназначен для 'resize' not' reserve'. ;) – avakar

4

Емкость не снизится. Я не уверен, что стандарт указывает это явно, но подразумевается: итераторы и ссылки на элементы вектора не должны быть аннулированы resize(n), если n < capacity().

0

Как я проверял на gcc (mingw), единственный способ освободить векторную емкость - это то, что говорит mattnewport. Сворачивание его с другим вектором вектора. Этот код делает это для gcc.

template<typename C> void shrinkContainer(C &container) { 
    if (container.size() != container.capacity()) { 
     C tmp = container; 
     swap(container, tmp); 
    } 
    //container.size() == container.capacity() 
} 
Смежные вопросы