堆栈仅在调试配置C ++中损坏

时间:2014-10-04 17:17:20

标签: c++ registry stack-corruption

我试图通过注册表获取某个程序的版本。在发布配置上设置时,我的代码工作正常。当我尝试在调试模式下运行它时,我的代码在离开此函数时崩溃了#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;
}

任何想法如何解决?

3 个答案:

答案 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恰好在返回实际使用的字节数时更新该值。