我有一个std::wstring decode(const char *s)
功能。
我用这样的:
const char *src = "some string";
const wchar_t *result = decode(src).c_str();
我总是在垃圾result[0]
中,有时result[1]
也。
我不,当我以另一种方式使用它得到的垃圾:
std::wstring res = decode(src);
const wchar_t *result = res.c_str();
我的decode
功能定义如下,它也它的工作。 唯一的问题是调用代码(上图)。
std::wstring decode(const char *s, UINT cp=CP_ACP)
{
if(s == NULL)
return std::wstring();
int length = ::MultiByteToWideChar(cp, 0, s, -1, NULL, 0 );
wchar_t *buf = new wchar_t[length];
::MultiByteToWideChar(cp, 0, s, -1, buf, length);
std::wstring r(buf);
delete[] buf;
return r;
}
我使用Visual C ++ 2008 SP1进行编译。
const wchar_t *result = decode(src).c_str();
的返回值decode
是临时值和调用之后销毁c_str()
从而result
点释放的内存。
因此,无论
- 延伸的返回值的寿命(其分配给一个局部变量,例如)
- 复制结果
12.2临时对象[class.temporary]
3当实现引入了具有一个非平凡的构造(12.1,12.8)一类的临时对象时,它必须确保一个构造函数被调用的临时对象。 同样,析构函数应被称为用于与非平凡的析构函数(12.4)的临时。 临时对象被销毁作为评价充分表达(1.9)是(词法)包含了他们所创建点的最后一步。 即使评价抛出异常结束。这是真实的。 值的计算和销毁临时对象的副作用仅与全表达相关,不与任何特定的子表达式。
所以,不要使用一个临时它在你的第一个例子中被毁后,等。
您的具体问题的答案既可提供了良好的答案被发现。 由于问题的标题是简单地wstring::c_str() contains garbage
我要指出的方式来得到的结果是不正确的decode
功能。
微软增加了许多ATL转换宏和类的宽字符(Unicode)和MBCS(ASCII)之间的转换。 他们可在VS2008。 支持的转换可以在找到MSDN文档 :
ATL 7.0引入了几个新的转换类和宏,提供比现有的宏显著的改善。 新的字符串转换类和宏的名称的形式为:C 2 SourceType中[C] DestinationType [EX]。
[剪断]
SourceType中/ DestinationType
A = ANSI字符串。
W = Unicode字符的字符串。
T =通用字符串(相当于至W _UNICODE被定义时,相当于一个其它)。
OLE = OLE字符串(相当于W)。
在[EX]
是可选的,经常使用的,如果你不想指定获取与宏中使用默认的内部缓冲区的大小。
在你的情况下,转换宏CA2W
(转换ASCII到Widechar)应该做你想要什么。 你只需要#include <atlbase.h>
使用它们。 这些宏采取2个参数 - 要转换的串和代码页(如果未指定默认为CP_ACP)
在你的情况有:
std::wstring res = decode(src);
const wchar_t *result = res.c_str();
使用ATL转换宏,你可以这样来做:
std::wstring res = CA2W(src, CP_ACP);
const wchar_t *result = res.c_str();
由于宏默认ANSI代码页,你也可以留下过CP_ACP是这样的:
std::wstring res = CA2W(src);
const wchar_t *result = res.c_str();
关于与同样的道理也适用于由这些宏返回的类临时对象的问题。 微软甚至文档与先前提供的链接不正确的使用示例这个问题:
// Example 3
// Incorrect use of conversion macros.
void ExampleFunction3(LPCWSTR pszW)
{
// Create a temporary instance of CW2A,
// save a pointer to it and then delete
// the temportary instance.
LPCSTR pszA = CW2A(pszW);
// The pszA in the following line is an invalid pointer,
// as the instance of CW2A has gone out of scope.
ExampleFunctionA(pszA);
}