Специфическое поведение std :: string в visual studio? - PullRequest
6 голосов
/ 05 декабря 2011

У меня есть проект, в котором мне нужно для чтения / записи больших файлов.

Я решил использовать ifstream :: read (), чтобы поместить эти файлы в память за один проход, в std :: string. (кажется, это самый быстрый способ сделать это в C ++: http://insanecoding.blogspot.com/2011/11/how-to-read-in-file-in-c.html и http://insanecoding.blogspot.com/2011/11/reading-in-entire-file-at-once-in-c.html)

При переключении между файлами мне нужно «сбросить» std :: string, использованную в качестве предыдущего буфера памяти (т. Е. Стереть буфер char [], чтобы освободить память)

Я пытался:

std::string::clear()
std::string::assign("")
std::string::erase(0, std::string::npos)
std::string::resize(0)
std::string::reserve(0)

но в Visual Studio 2008 это не освобождает память, используемую внутри самой std :: string: ее базовый буфер не выделяется.

Единственный способ найти его - это вызвать std :: string :: swap (std :: string ("")) для принудительного изменения внутренних буферов между фактическим std :: string и пустым параметром.

Я нахожу это поведение немного странным ...

Я тестировал только на Visual Studio 2008, я не знаю, является ли это поведением стандарта STL или оно специфично для MSVC.

Не могли бы вы дать мне подсказку?

1 Ответ

4 голосов
/ 27 декабря 2011

Как прокомментировали Влад и Альф, std::string().swap(the_string) - это способ C ++ 98 для освобождения емкости the_string, а the_string.shrink_to_fit() - это способ C ++ 11.

Относительно того, почему clear(), erase(), resize() и т. Д. Не делают этого, это оптимизация для сокращения выделений, когда вы используете строку снова и снова. Если clear() освободит емкость строки, вам, как правило, придется перераспределить аналогичный объем пространства на следующей итерации, что может занять некоторое время, которое реализация может сэкономить, сохранив емкость. Эта реализация не гарантируется стандартом, но она очень распространена в реализациях.

reserve() задокументировано с

Вызов функции Reserve () с аргументом res_arg, меньшим емкости (), фактически является необязательным запросом сжатия. Вызов с res_arg <= size () по сути является необязательным запросом сжатия к размеру. </p>

, что означает, что реализации с большей вероятностью освободят емкость при вызове reserve(). Если я правильно их читаю, libc ++ и libstdc ++ освобождают место при вызове reserve(0), но вполне вероятно, что библиотека VC ++ сделала противоположный выбор.

Редактировать: Как говорит Пенелопа, поведение std::string здесь, как правило, точно такое же, как и поведение std::vector.

...