std::string 在 Visual Studio 上的具体行为?

发布于 2024-12-19 17:14:47 字数 977 浏览 2 评论 0原文

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

我决定使用 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 和 param 中的空缓冲区之间的内部缓冲区。

我发现这种行为有点奇怪...

我只在 Visual Studio 2008 上测试过,我不知道它是 STL 标准行为还是 MSVC 特定的行为。

你能给我一些线索吗?

I've got a project in which I need to read/write large files.

I've decided to use ifstream::read() to put those files into memory in one single pass, into an std::string.
(that seems to be the fastest way to do it in c++ : http://insanecoding.blogspot.com/2011/11/how-to-read-in-file-in-c.html and
http://insanecoding.blogspot.com/2011/11/reading-in-entire-file-at-once-in-c.html)

When switching between files, I then need to "reset" the std::string used as the previous memory buffer (ie, erase the char[] buffer to free memory)

I tried :

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

but, under Visual Studio 2008, this doesn't free the memory used inside the std::string itself : its underlying buffer isn't de-allocated.

The only way I found to delete it is to call std::string::swap(std::string(""))
to force changing the internal buffers between the actual std::string and the empty one in param.

I find this behaviour a bit strange...

I only tested on Visual Studio 2008, I don't know if it's a STL-standard behaviour or if it's MSVC-specific.

Could you get me some clue ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

許願樹丅啲祈禱 2024-12-26 17:14:47

正如 Vlad 和 Alf 所评论的,std::string().swap(the_string) 是释放 the_string 容量的 C++98 方式,而 the_string .shrink_to_fit() 是 C++11 方式。

至于为什么clear()erase()resize()等不这样做,这是为了减少当您一遍又一遍地使用字符串时的分配。如果 clear() 释放了字符串的容量,您通常必须在下一次迭代中重新分配类似数量的空间,这将需要一些时间,实现可以通过保留容量来节省。标准不保证这种实现,但它在实现中很常见。

reserve() 记录为

使用小于capacity()的res_arg参数调用reserve()实际上是一个非绑定收缩请求。使用 res_arg <= size() 的调用实际上是一个非绑定的收缩以适应请求。

这意味着实现更有可能在 reserve() 调用上释放容量。如果我没看错的话, libc++当您调用 reserve(0) 时,libstdc++ 会释放空间,但 VC++ 的库做出相反的选择似乎是合理的。

编辑:正如 penelope 所说,这里的 std::string 行为往往与 std::vector 的行为完全相同。

As Vlad and Alf commented, std::string().swap(the_string) is the C++98 way to release the_string's capacity, and the_string.shrink_to_fit() is the C++11 way.

As to why clear(), erase(), resize(), etc. don't do it, this is an optimization to reduce allocations when you use a string over and over. If clear() freed the string's capacity, you'd generally have to reallocate a similar amount of space on the next iteration, which would take some time the implementation can save by keeping the capacity around. This implementation isn't guaranteed by the standard, but it's very common in implementations.

reserve() is documented with

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.

which implies that implementations are more likely to release the capacity on a reserve() call. If I'm reading them right, libc++ and libstdc++ do release space when you call reserve(0), but it's plausible for VC++'s library to have made the opposite choice.

Edit: As penelope says, std::string's behavior here tends to be exactly the same as std::vector's behavior.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文