【问题标题】:C++ std:string memory modelC++ std:string 内存模型
【发布时间】:2011-03-22 13:41:34
【问题描述】:

以下代码(网络服务器中的请求-响应循环的一部分)大部分时间都可以工作,但有时会失败,因为客户端会报告它已经获得了一些奇怪的其他字符串(似乎是来自附近位置的随机字节此函数中的内存,或空字节)。

string res = "";
if (something) {
    res = "ok";
}

if (res.length() > 0) {
    send_data((void*) res.c_str(), res.length());
}

在我看来,"" 和 "ok" 似乎都是常量 std:strings,而 res 是指向其中任何一个的指针,因此整个事情应该可以工作,但显然情况并非如此,那么有人可以向我解释一下这里发生了什么吗?

【问题讨论】:

  • 您的send_data() 是否有可能是非阻塞的,而您在完成之前正在销毁res
  • 钱是对的。我在这里使用 0MQ,并且我正在尝试发送数据的非复制方式,但显然在这种情况下不能正常工作。谢谢!
  • c_str() 的返回值所指向的数据只保证在下一次调用res 的非常量成员函数之前有效。具体来说,如果 res 被破坏,例如超出范围,那么之前由 res.c_str() 返回的值将不再有效。

标签: c++ string memory


【解决方案1】:

您可能忘记发送空终止符来表示字符串的结尾:

send_data((void*) res.c_str(), res.length()+1);

【讨论】:

  • 这至少不会给我一些类似于我想发送的字符串的东西,但添加了垃圾?这里不是这种情况(这在我的问题中是隐含的,但并不完全清楚)。
  • 是的 - 除非是空字符串,否则不会发送任何内容(由于 if 子句)。
【解决方案2】:

您的代码没问题,我想您的程序中存在一些内存损坏。

"" 和 "ok" 实际上是 'const char *' 类型的以零结尾的缓冲区,而不是字符串。当您将它们分配给您的字符串时,它们的所有数据都将复制到字符串内部缓冲区中,不包括最后一个为零的字符,所以

res = "";

将清除内部字符串缓冲区,res.length() 将变为0。

res.c_str() 将返回该缓冲区的地址,而不是 "" 或 "ok" 文字的地址。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-10
    • 2018-09-04
    • 2011-10-16
    • 2018-04-20
    • 2012-08-25
    • 2013-01-06
    • 1970-01-01
    相关资源
    最近更新 更多