我编写了一个名为ws2s的函数,将wstring转换为字符串:
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();
答案 0 :(得分:4)
在第一个方法中,调用函数并将结果分配给局部变量。然后,您获得指向string
对象保存的数据的指针。一切都很好,并且是执行此操作的正确方法。
在第二种方法中,您调用函数并将变量的指针分配给临时结果对象保存的数据。然后,临时对象at the end of the full expression被破坏,释放变量所指向的数据。这将创建一个悬空指针,其取消引用会导致未定义的行为。
如果只需要在表达式的末尾之前使用指针(而不复制它),则可以使用这种语法,例如:
std::strcmp(ws2s(something).c_str(), "test");
答案 1 :(得分:2)
在第二个示例中,在调用ws2s
之后销毁了临时对象(返回值.c_str()
),因此您在path
中的指针无效。
当然,在第一个示例中,情况并非如此,只要保持xml_path
,指针就有效。