将 wostringstream 转换为 wchar_t* 乱码值
Posted
技术标签:
【中文标题】将 wostringstream 转换为 wchar_t* 乱码值【英文标题】:Converting wostringstream to wchar_t* Garbles Values 【发布时间】:2014-12-31 00:38:37 【问题描述】:我正在尝试生成一个字符串并将其分配给wchar_t*
,但是当我去分配它时,似乎有些东西会混淆字符串。这是一个简化的重现:
wostringstream woss;
woss << L"Test String";
// A: this doesn't work:
const wchar_t* foo = woss.str().c_str();
wcout << foo << endl; // "????????????????????????"
// B: this works:
wstring bar = woss.str();
const wchar_t* foo = foo.c_str();
wcout << foo << endl; // "Test String"
// C: this also works!?:
const wchar_t* foo = woss.str().c_str();
wstring bar = woss.str();
wcout << foo << endl; // "Test String"
当我一次完成所有转换时(如 A),foo
指向的结果值是一堆0xFEEE
字符。但是,如果我一步一步地做(如在 B 中),字符串最终会很好。最奇怪的是,如果在赋值后,我评估woss.str()
,foo
指向的数据突然变为有效(如在C中)。 p>
这让我认为,链式赋值以某种方式返回了一个指向字符最终将去哪里的指针,但它以某种方式跳过了str()
的实际评估,因此实际上并没有填充那里的值。只有当我调用str()
(在指针赋值之前或之后)时,数据才会出现在正确的位置。问题是,我不知道什么会导致这种行为......
如果它是相关的,这一切都在辅助线程上运行,但我不认为这很重要,因为我只处理局部变量。想法?
【问题讨论】:
只有一个字。阅读utf8everywhere.org @PavelRadzivilovsky 实际上,这段代码正在填充 Win32LPCTSRT
结构成员,因此很遗憾必须使用宽字符。不过,好文章。
【参考方案1】:
wostringstream::str()
方法返回一个std::wstring
按值。您没有将其分配给任何东西,因此它的生命周期是暂时的,并在表达式完成时结束。您正在调用 std::wstring::c_str()
来保存指向临时数据的指针,然后临时数据被破坏,留下一个杂散的指针,从而在您的后续代码中导致 undefined behavior。
不保存std::wstring
的数据指针,而是保存实际的std::wstring
对象,并仅在实际需要时检索其数据指针。
【讨论】:
所以简而言之,B 是正确使用的模式。我过去一直使用链式方法,但我猜那只是在函数调用参数的上下文中,所以指针在调用返回之前是有效的。以上是关于将 wostringstream 转换为 wchar_t* 乱码值的主要内容,如果未能解决你的问题,请参考以下文章
visual c++ 2013 内存泄漏 wostringstream、imbue 和语言环境方面