我试图通过注册表获取某个程序的版本。在发布配置上设置时,我的代码工作正常。当我尝试在调试模式下运行它时,我的代码在离开此函数时崩溃了#34;运行时检查失败#2 - 堆栈变量'版本'已经腐败"。
我只会粘贴我的函数的相关代码。那是"版本"出现在我的代码中。当我调试它时,版本获得适当的值。代码在发布配置中不会崩溃。对于我设置的两种配置"使用多字节字符集"。
TCHAR version[20];
DWORD dwBufferSize = 0;
if (RegQueryValueEx(hAppKey, "DisplayVersion", NULL,&dwType, (unsigned char*)version, &dwBufferSize) == ERROR_SUCCESS)
{
dwBufferSize = 20;
std::string vers(version, dwBufferSize);
return vers;
}
任何想法如何解决?
答案 0 :(得分:1)
您的代码不在发布时工作正常。它包含一个缓冲区溢出,这是包含额外错误检查的调试版本正在接受的。
粗略一瞥[{3}}显示你在做什么是错的:
LONG WINAPI RegQueryValueEx(
_In_ HKEY hKey,
_In_opt_ LPCTSTR lpValueName,
_Reserved_ LPDWORD lpReserved,
_Out_opt_ LPDWORD lpType,
_Out_opt_ LPBYTE lpData,
_Inout_opt_ LPDWORD lpcbData
);
lpcbData [in,out,optional] 指向变量的指针,该变量指定lpData参数指向的缓冲区大小(以字节为单位)。函数返回时,此变量包含复制到lpData的数据大小。
当你的缓冲区实际上是20 * sizeof(TCHAR)字节而不是0而不是20时,你告诉你的缓冲区大小为0。
每当你必须处理c风格的字符串时,请务必小心。这看起来就像是在您的代码中引入了一个安全漏洞。
答案 1 :(得分:0)
看起来你告诉它你的缓冲区大小为零。你为什么不说20?
答案 2 :(得分:0)
这似乎是错误的,因为它说你的缓冲区是0.但是是20 TCHAR:
DWORD dwBufferSize = 0;
应该是:
DWORD dwBufferSize = sizeof(version);
这很重要,因为它用于传递RegQueryValueEx
作为version
缓冲区的大小。 RegQueryValueEx
恰好在返回实际使用的字节数时更新该值。