c++ - std::string 在 vi​​sual studio 上的具体行为?

标签 c++ stl stdstring

我有一个项目需要读取/写入大文件。

我决定使用 ifstream::read() 一次性将这些文件放入内存,放入 std::string。 (这似乎是在 C++ 中最快的方法:http://insanecoding.blogspot.com/2011/11/how-to-read-in-file-in-c.htmlhttp://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 在 vi​​sual studio 上的具体行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8386639/

相关文章:

c++ - 执行后计数器for循环错误地递增

c++ - 我们什么时候应该选择其他IPC而不是直接内存访问来进行线程间通信

C++:考虑不使用反斜杠 (\) 的 C++ std::string 中双引号 (") 的字面含义

c++ - 你能在 std::getline 中指定什么不是定界符吗?

c++ - 如何通过在 Qt 中按 esc 退出无限 while 循环?

c++ - 使用空字符串 ""创建 std::locale

c++ - 将一对插入 std::vector 时的 emplace_back() 与 push_back

c++ - STL map 如何知道该 map 包含给定元素?

c++ - STL 中 project1st<Arg1, Arg2> 的用处是什么?

c++ - 如何将字符串添加到 vector (并随后显示它)?