在这种情况下,Win32错误码122是良性的吗?
Is Win32 error code 122 somewhat benign in this case?
GetLastError()
返回错误码122 (=ERROR_INSUFFICIENT_BUFFER)
CString str = CString("'") + _T("%s") + CString("'");
但是这只在VS2005下发生,而在VS2015中不会发生。我仍然没有看到内存损坏或任何东西在VS2005和str
变量包含正确的值。给出错误代码,这仍然是一个值得关注的问题吗?
发生这种情况的原因似乎是因为宽字符和简单字符串的连接,修复方法是简单地用_T("")
包围剩下的两个字符串,这样代码行看起来像:
CString str = CString(_T("'")) + _T("%s") + CString(_T("'"));
但是当原始行中只有一个字符串是Unicode时,错误码122真正意味着什么?到底发生了什么错误,还是在这种情况下更像是一种警告?
GetLastError()
仅在某些系统调用返回错误后才有意义。因为你的代码没有任何系统调用,所以GetLastError()
可以返回任何东西。
可能您看到的值是上次失败的系统调用的最后一个错误。或者可能是CString
类内部发生的一些错误,但它在那里处理。
TL,博士;
在VS 2015中,您可以使用CString("a")
(如果设置了Unicode)或CStringW("a")
来重现错误
#include <iostream>
#include <atlstr.h>
int main()
{
CStringW("a");
DWORD err = GetLastError();
std::cout << err << "n"; //<= error 122, ERROR_INSUFFICIENT_BUFFER
return 0;
}
这是因为CString
使用WinAPI MultiByteToWideChar
将ANSI "a"
转换为Unicode L"a"
。通过"atlmfcincludecstringt.h"
中的源代码进行调试,我们看到在某些地方它调用了以下函数:
static int __cdecl GetBaseTypeLength(_In_z_ LPCSTR pszSrc) throw()
{
// Returns required buffer size in wchar_ts
return ::MultiByteToWideChar( _AtlGetConversionACP(), 0, pszSrc, -1, NULL, 0 )-1;
}
由于某种原因,在末尾有一个-1
。我不知道为什么会这样,它可能是必要的其他CString
函数,但在这种情况下,它最终导致ERROR_INSUFFICIENT_BUFFER
错误在下一次调用MultiByteToWideChar
。转换可以大致简化为:
int main()
{
int nDestLength = MultiByteToWideChar(CP_ACP, 0, "a", -1, NULL, 0) - 1;
wchar_t *pszDest = new wchar_t[32];
//ERROR_INSUFFICIENT_BUFFER occurs here because nDestLength is short by 1:
MultiByteToWideChar(CP_ACP, 0, "a", -1, pszDest, nDestLength);
DWORD err = GetLastError();
std::cout << err << "n";
return 0;
}
nDestLength
太小,因为它没有考虑空终止符。CString
稍后整理,但错误仍然存在。这是不关注GetLastError
的一个很好的理由,除非函数失败。
正如您所注意到的,这个错误可以通过使用_T
宏来避免,因为CString
将不再需要MultiByteToWideChar
。或者使用L
前缀,或者CString::Format
CString str = CString(L"'") + L"%s" + CString(L"'");
- 我是c ++的新手,你能解释一下在这种情况下的指针吗
- 在这种情况下,java对象是否可以调用本机函数
- 在这种情况下显式调用时,std::cout 如何更改析构函数的行为?
- 在这种情况下,我真的复制了字节还是复制了字符?
- 为什么在这种情况下,bool 类型的输出等于 0?
- 在这种情况下,如何传递成员函数而不是函数?
- 为什么在这种情况下递增阵列名称有效?
- 在这种情况下我应该使用哪种设计模式
- 为什么在这种情况下我需要 .template
- 在这种情况下,使用 string_view 是否会导致不必要的字符串复制?
- 我是否访问了已释放的内存,或者在这种情况下DrMemory报告不正确?
- 在这种情况下,"typename..."意味着什么?
- 为什么在这种情况下 x = 44?
- 在这种情况下是私有的吗?试图使操作员<<过载
- 在这种情况下,如何防止C++输出/控制台窗体关闭
- 为什么 lambda nullptr 取消引用在这种情况下有效?
- 为什么在这种情况下,前向声明不起作用?
- 为什么在这种情况下不调用我的虚拟函数实现?
- 在这种情况下,为什么模板即时深度超过限制?
- 在这种情况下,Win32错误码122是良性的吗?