7

我正在尝试更多地了解 C++ 字符串。

考虑

const char* cstring = "hello";
std::string string(cstring);

std::string string("hello");

我是否正确假设两者都在应用程序的 .data 部分存储“hello”,然后将字节复制到堆上的另一个区域,由 std::string 管理的指针可以访问它们?

我怎样才能有效地存储一个非常长的字符串?我有点想从套接字流中读取数据的应用程序。我害怕连接很多次。我可以想象使用一个链表并遍历这个列表。

弦乐吓唬我太久了!

任何链接、提示、解释、更多细节都会非常有帮助。

4

4 回答 4

3

我已经将字符串存储在 10 或 100 的 MB 范围内,没有问题。自然,它将主要受您可用(连续)内存/地址空间的限制。

如果您要追加/连接,有几件事可能有助于提高效率:如果可能,请尝试使用 reserve() 成员函数来预分配空间——即使您对如何进行粗略了解最终大小可能很大,随着字符串的增长,它将避免不必要的重新分配。

此外,许多字符串实现使用“指数增长”,这意味着它们增长了某个百分比,而不是固定的字节大小。例如,只要需要额外的空间,它就可以简单地将容量翻倍。通过以指数方式增加大小,执行大量连接变得更加有效。(具体细节取决于您的 stl 版本。)

最后,另一个选择(如果你的库支持的话)是使用rope<>模板:Ropes 类似于字符串,除了它们在对非常大的字符串执行操作时效率更高。特别是,“绳索被分配在小块中,显着减少了大块引入​​的内存碎片问题”。有关SGI 的 STL 指南的一些其他详细信息。

于 2011-04-23T22:06:49.293 回答
2

由于您正在从套接字读取字符串,因此您可以重用相同的数据包缓冲区并将它们链接在一起以表示巨大的字符串。这将避免任何不必要的复制,并且可能是最有效的解决方案。我似乎记得ACE库提供了这样的机制。我会试着找到它。

编辑: ACE 有 ACE_Message_Block 允许您以链表方式存储大消息。您几乎需要阅读 C++ 网络编程书籍才能理解这个庞大的库。ACE 网站上的免费教程真的很烂。

我敢打赌, Boost.Asio必须能够做与 ACE 的消息块相同的事情。Boost.Asio 现在似乎比 ACE 拥有更大的份额,所以我建议先在 Boost.Asio 中寻找解决方案。如果有人能启发我们有关 Boost.Asio 解决方案的信息,那就太好了!


是时候尝试使用 Boost.Asio 编写一个简单的客户端-服务器应用程序,看看有什么大惊小怪的了。

于 2011-04-24T00:49:02.087 回答
1

我不认为效率应该是问题。两者都会表现得足够好。

这里的决定因素是封装。 是一个比以往任何时候都std::string好得多的抽象。char *封装指针算术是一件好事。

很多人想了很久,也很难想出std::string。我认为出于毫无根据的效率原因而未能使用它是愚蠢的。坚持更好的抽象和封装。

于 2011-04-23T22:07:14.547 回答
0

您可能知道,anstd::string实际上只是basic_string<char>.

也就是说,它们是一个序列容器,内存将按顺序分配。如果您尝试使 std::string 大于您可以分配的可用连续内存,则可能会从 std::string 中获取异常。由于内存碎片,此阈值通常远小于总可用内存。

例如,在尝试为图像分配大型连续 3D 缓冲区时,我遇到了分配连续内存的问题。但是这些问题至少不会在 100MB 左右开始发生,至少根据我的经验,在 Windows XP Pro 上(例如)。

你的琴弦有这么大吗?

于 2011-04-23T22:17:08.907 回答