2014-10-04 73 views
0

我想通過註冊表獲取某些程序的版本。我的代碼在發佈配置時設置正常。當我嘗試在調試模式下運行它時,我的代碼在離開此函數時出現消息「運行時檢查失敗#2 - 變量'版本'周圍的堆棧已損壞」時崩潰。堆棧損壞只用於調試配置C++

我只會粘貼我的函數的相關代碼。這就是我的代碼中的所有「版本」外觀。當我調試它時,版本會獲得適當的價值。代碼不會在發佈配置中崩潰。對於這兩種配置,我都設置了「使用多字節字符集」。

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

看起來像你告訴它,你的緩衝區大小爲零。你爲什麼不說20呢?

+0

當然不是所有的代碼。它被設置爲20.否則它不適用於發佈配置。 – 2014-10-04 17:33:10

+0

@IggyBrodevíć:那麼你沒有向我們展示足夠的相關代碼。因爲它代表'DWORD dwBufferSize = 0;'後面跟'RegQueryValueEx'就是錯誤的。如果你真的這樣做並且在Release中運行它,它可能看起來正確地做了正確的事情,但事實上它只是錯誤的。如果這不是你的代碼所做的事情,你需要提供真正代表你真正問題的代碼。 – 2014-10-07 13:41:11

+0

沒有看到更多相關的代碼。我最好的猜測是你的問題。在你的真實代碼中,你將dwBufferSize設置爲一個大於sizeof(版本)的值。我使用sizeof(),因爲TCHAR可能是1或2字節,儘管你說你用MBCS構建它會使它成爲20.堆棧損壞表明你先寫'version'緩衝區,並擦除用於檢測堆棧是否損壞的警戒位。另一種可能性是你遺漏了處理覆蓋緩衝區的'version'的其他代碼。你有沒有在最大緩衝區末尾附加一個nul(\ 0)終止字符? – 2014-10-07 13:46:26

0

這似乎是因爲它說你的緩衝區爲0是錯誤的,但在20 TCHAR:

DWORD dwBufferSize = 0; 

也許應該是:

DWORD dwBufferSize = sizeof(version); 

,因爲這是用來傳遞這是很重要到RegQueryValueEx作爲version緩衝區的大小。 RegQueryValueEx只是在它返回實際使用的字節數時更新該值。

1

您的代碼確實是而不是在發佈中正常工作。它包含一個緩衝區溢出,這是包含額外錯誤檢查的調試版本正在採用的內容。

粗略地看一眼at the documentation for RegQueryValueEx顯示你在做什麼是錯的:

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 [輸入,輸出,可選] 指向一個變量指定緩衝區的大小指出,通過lpData參數,以字節爲單位。當函數返回時,該變量包含複製到lpData的數據的大小。

你告訴你的緩衝區大小爲0的功能時,它實際上是20 *的sizeof(TCHAR)字節,而不是0,而不是20

請仔細超級每當你要處理C風格的字符串。這看起來像是在您的代碼中引入安全漏洞。