为什么std::strstream已被弃用?

83

我最近发现 std::strstream 已被弃用,推荐使用 std::stringstream。虽然我已经有一段时间没有使用它了,但是在那个时候它确实能够满足我的需求,因此听到它已被弃用感到惊讶。

我的问题是,为什么做出这个决定,并且 std::stringstream 提供的哪些优点在 std::strstream 中不存在?


@Chris Lively:你是在说这只是一个命名约定问题,还是你只是在开玩笑? - andand
我不确定,但是通过Google找到的此URL可能会有所帮助:http://bytes.com/topic/c/answers/158338-strstream-depreciation - Will Bickford
1
@andand 检查一下 Exceptional C++,那里有很好的解释。 - There is nothing we can do
1
@Christ Lively:感谢您的澄清。我以为您可能在开玩笑,但有时很难分辨。 - andand
虽然已经晚了将近4年,但我想补充一下,strstream 已经在每个标准中被弃用了,我仍然感到困惑的是为什么它们曾经被添加到标准中... - MFH
显示剩余2条评论
4个回答

103

strstream返回的char *非常难以管理,因为没有地方说明它是如何分配的。因此不可能知道你是否应该删除它或调用free()函数或完全做其他事情。唯一真正令人满意的释放它的方法是通过freeze()函数将其交还给strstream。这是非常不明显的,很多人都会做错。而stringstream返回一个自我管理的字符串对象,这要容易得多,也不容易出错。

还有使用ends终止字符串的问题,但我认为释放内存的问题是弃用的主要原因。


2
一个友元锁定访问器可以解决这个问题,而不需要制作当前解决方案中的数据副本。{ std::bufferguard f(mystream); printf("%s\n", f.str()); } - Erik Aronesty
人们使用strstream只是因为他们想要控制内存管理。 - Martin Kosicky
我认为std::stringstream永远不会完全取代std::strstream。在某些方面,std::strstreamstd::stringstream更加出色。幸运的是,在C++23中我们将有std::spanstream可用。 - frozenca

17

更易理解的内存管理。(有人能记住谁负责释放分配的内存以及在什么情况下吗?)

(请注意,由于strstream仍提供了一些其他地方不可用的东西,它将继续存在于C++0X中--至少在我检查过草案时是这样的)。


5
如果你提供缓冲区,你需要负责释放它。如果它提供了缓冲区,它会自行释放,但你需要记得解冻流,否则它不会释放。c_str = stream.str(); /*使用 c_str*/ stream.freeze(false); - Dennis Zickefoose

12

strstream构建一个char *。而std::stringstream构建一个std::string。我认为strstream已经被弃用,因为存在缓冲区溢出的潜在风险。而std::string则自动防止了这种情况。


strstream实际上并不构建char *,它只是在内部分配的缓冲区末尾添加了一个null。问题在于奇怪的访问器“freeze”...应该被实现为一个保护。 - Erik Aronesty

7

从个人角度来看,我曾多次遇到不明显的内存损坏问题,这些问题需要花费数天或数周才能追踪,最终发现是使用了 strstream。一旦将其替换为stringstream,问题就解决了,我也不再深究了!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接