Должен ли я всегда вызывать vector clear() в конце функции?
У меня есть простая функция, которая использует вектор, подобный этому (псевдокод):
void someFunc(void) {
std::vector<std::string> contentVector;
// here are some operations on the vector
// should I call the clear() here or this could be ommited ?
contentVector.clear();
}
Должен ли я вызвать clear(), или это может быть пропущено?
Ответы
Ответ 1
Если мы посмотрим на cppreference.com для std::vector:: ~ vector в нем говорится:
Уничтожает контейнер. Вызывается деструкторы элементов, и используемое хранилище освобождается. Обратите внимание, что если элементы являются указателями, объекты с указателем не уничтожаются.
так что вам не нужно вызывать clear.
Если мы хотим перейти в черновик стандарта, мы должны рассмотреть раздел 23.2.1
Общие требования к контейнерам, абзац 4, который гласит:
В таблицах 96 и 97 X обозначает класс контейнера, содержащий объекты типа T, a и b обозначают значения типа X, [...]
а затем посмотрите Table 96 — Container requirements
, который имеет следующую запись выражения:
(&a)->~X()
и следующее примечание:
note: деструктор применяется к каждому элементу a; вся память освобождается.
Обновить
Это RAII в действии, и как говорит Бьярне Страуструп в Почему 't С++ предоставляет "окончательную" конструкцию?:
Потому что С++ поддерживает альтернативу, которая почти всегда лучше: метод "сбора ресурсов - это инициализация" (раздел TС++ PL3, раздел 14.4). Основная идея заключается в представлении ресурса локальным объектом, так что локальный объект-деструктор освободит ресурс. Таким образом, программист не может забыть выпустить ресурс.
Ответ 2
Абсолютно не нужно этого делать. std::vector
, и все остальные контейнеры автоматически уничтожают их элементы, когда они сами будут уничтожены. Это означает, что их деструкторы несут ответственность за это действие. Итак, не надо.
Красота этого заключается в том, что контейнеры, естественно, безопасны для защиты [1]:
void someFunc(void) {
std::vector<std::string> contentVector;
// here are some operations on the vector
throw std::runtime_error("I just want to throw!");
contentVector.clear();
}
Будет ли вызываться линия contentVector.clear();
? Нет. Но вы все еще в безопасности, потому что гарантируется, что будет вызван деструктор contentVector
.
Из vector [2]:
Уничтожает контейнер. Вызывается деструкторы элементов, и используемое хранилище освобождается. Обратите внимание, что если элементы являются указателями, объекты с указателем не уничтожаются.
[1] Вам все равно нужно сделать свои элементы исключительными, хотя (правильно ли они освобождают свои ресурсы при вызове их деструкторов).
[2] См. комментарии ниже для некоторых мыслей о документах SGI STL.
Ответ 3
Нет необходимости, он автоматически очистится после того, как он выйдет за пределы видимости. деструктор уничтожит объект контейнера.
Ответ 4
Так как я не думаю, что кто-то еще упомянул об этом, но если ваш вектор был
std::vector<std::string*> vector;
вы должны освободить память, выделенную для каждого элемента, до завершения функции (если вы не передали право собственности на другое место, например глобальную переменную и т.д.)
for (auto i : vector) {
delete i;
}
Ответ 5
Вы можете опустить с помощью функции .clear(), потому что vector destructor запускается после того, как contentVector выходит из области видимости в '}'.
Отменяет память, в которой хранятся векторные данные.