这两种方式有什么区别吗?

Is there any difference between these two ways?

本文关键字:区别 什么 两种 方式      更新时间:2023-10-16

我写了一个名为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();

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

在第二种方法中,调用函数并为变量分配指向临时结果对象所持有数据的指针。然后,在完整表达式的末尾销毁临时对象,释放变量指向的数据。这将创建一个悬空指针,其取消引用会导致未定义的行为。

如果您只需要在表达式末尾之前使用指针(不复制它(,则可以使用此类语法,例如:

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

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

当然,在第一个例子中,情况并非如此,只要您保持xml_path,指针就会有效。