我有一个项目需要读取/写入大文件。
我决定使用 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。
你能给我一些线索吗?
最佳答案
正如 Vlad 和 Alf 评论的那样,std::string().swap(the_string)
是释放 the_string
容量的 C++98 方式,并且 the_string.shrink_to_fit()
是 C++11 的方式。
至于为什么clear()
、erase()
、resize()
等不做,这是一个反复使用字符串时减少分配的优化。如果 clear()
释放了字符串的容量,您通常必须在下一次迭代中重新分配类似数量的空间,这将花费一些时间,实现可以通过保持容量来节省时间。此实现不受标准保证,但在实现中很常见。
reserve()
记录在
Calling reserve() with a res_arg argument less than capacity() is in effect a non-binding shrink request. A call with res_arg <= size() is in effect a non-binding shrink-to-fit request.
这意味着实现更有可能在调用 reserve()
时释放容量。如果我没看错的话,libc++和 libstdc++ 确实会在您调用 reserve(0)
时释放空间,但 VC++ 的库做出相反的选择是合理的。
编辑:正如 penelope 所说,std::string
在这里的行为往往与 std::vector
的行为完全相同。
关于c++ - std::string 在 visual studio 上的具体行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8386639/