【问题标题】:Is there any difference between these two ways? [duplicate]这两种方式有什么区别吗? [复制]
【发布时间】:2019-02-11 06:53:46
【问题描述】:

我写了一个叫ws2s的函数把wstring转成string:

std::string ws2s(const std::wstring & src)
{ 
   std::string res = "";

   size_t const mbs_len = wcstombs(NULL, src.c_str(), 0);

   std::vector<char> buffer(mbs_len + 1);

   wcstombs(&buffer[0], src.c_str(), buffer.size());

   res.assign(buffer.begin(), buffer.end() - 1);

   return res;
}

我使用 valgrind 运行内存检查有一些错误。这两种调用函数ws2s的方式有什么区别吗?

第一种方法:

std::string xml_path = ws2s(something);
const char * path = xml_path.c_str();

第二种方法:

const char * path = ws2s(something).c_str();

【问题讨论】:

  • 你展示的代码明明是C++,为什么还要加C语言标签?
  • 当询问“错误”时,请始终包含实际错误。复制粘贴为文本,完整而完整。并且不要忘记还包括生成错误的minimal reproducible example。请花一些时间阅读有关 how to ask good questionsthis question checklist 的信息。
  • @Someprogrammerdude valgrind 错误似乎太长,代码有6k行,没人想看。
  • @J.Doe - 你是对的,没有人愿意阅读 6k 行,这就是为什么你被指向 Minimal、完整和可验证的示例页面来学习如何做好一个。
  • @slawekwin 谢谢,这是同一个问题。

标签: c++ string char


【解决方案1】:

在第一种方法中,您调用函数并将结果分配给局部变量。然后你得到指向string 对象持有的数据的指针。这一切都很好,而且是正确的方法。

在第二种方法中,您调用函数并为变量分配一个指向临时结果对象保存的数据的指针。然后销毁临时对象at the end of the full expression,释放变量指向的数据。这会创建一个悬空指针,其取消引用会导致未定义的行为。

如果您只需要在表达式结尾之前使用指针(不复制它),您可以使用这样的语法,例如:

std::strcmp(ws2s(something).c_str(), "test");

【讨论】:

    【解决方案2】:

    在第二个例子中,临时对象(返回值ws2s)在调用.c_str()后被销毁,因此path中的指针无效。

    在第一个例子中,当然不是这样,只要保持xml_path,指针就会有效。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-13
      • 2020-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多