#cpp #cpp11 #vector #stl #cpp14
Подскажите пожалуйста, если у меня есть контейнер и я знаю сколько в нем примерно будет элементов, для ускорения работы я могу выделить их изначально, например так: std::vectorstorage; storage.reserve(10000); а что происходит, когда я вычищаю элементы из контейнера? storage.clear(); Нужно ли мне опять зарезервировать объем или можно ли сделать такой clear(), чтобы осталась зарезервированная память
Ответы
Ответ 1
Функция clear не освобождает зарезервированную память. Чтобы она освободилась, нужно после clear вызвать shrink_to_fit.Ответ 2
Согласно документации по методу std::vector::clear() (вольный перевод): Изменение фактического размера блока памяти не гарантируется, а потому отсутствует и гарантия изменения вместимости вектора. Для принудительного освобождения памяти необходимо использовать swap: vector().swap(x); // высвобождаем память из-под x A reallocation is not guaranteed to happen, and the vector capacity is not guaranteed to change due to calling this function. A typical alternative that forces a reallocation is to use swap: vector ().swap(x); // clear x reallocating Причина — дороговизна обращения к диспетчеру памяти. Ведь он должен взять глобальную блокировку, по крайней мере частично пробежаться по списку выделенных блоков и иногда выполнить слияние смежных свободных блоков. Так что можно спокойно закладываться на то, что память повторно резервировать не надо. Ответ 3
Да, нужно повторно вызывать reserve. После очистки с помощью clear вектор формально считается пустым и вы не должны делать предположений о том что фактически сделал вектор с памятью. Так как стандарт ничего такого не требует и не обещает, то есть вектор может освободить всю память, ее часть или ничего не освобождать. Ничего страшного не произойдет если память не освободится, а вы повторно вызвали reserve. С другой стороны если память освободится, ваш повторный вызов reserve сделает то же что и первый - зарезервирует нужное количество памяти.Ответ 4
Т.е. из всего вышесказанного все таки выходит, что если работа с контейнером идет постоянно, то можно не особо заморачиваться после вычищения контейнера с резервированием памяти, поскольку старая не отдается системе и может быть использована повторно? Будет тот же эффект, как будто я каждый раз резервирую память, т.е. при операциях добавления элемента лишнее время на выделение памяти под элемент тратиться не будет.
Комментариев нет:
Отправить комментарий