2013-04-22 107 views
2

所以我是一個非常大的新的C++,所以我敢肯定這是一個相對簡單的問題,但我有一個傳統的C++應用程序我試圖跟蹤堆腐敗問題並已將其被曝此功能:堆損壞錯誤與刪除[]

void LTrimZeros(CString *pstr) 
{ 
    char *psz1; 
    char *psz2; 

    if (pstr->GetLength() == 0) 
     return; 


    psz1 = new char[pstr->GetLength() + 1]; 
    psz2 = psz1; 

    strcpy_s(psz2, strlen(psz2), (const char *) *pstr); 

    while (*psz2 == '0') 
    { 
     psz2++; 
    } 

    *pstr = psz2; 

    delete [] psz1; 

    return; 
} 

當它試圖刪除psz1它拋出一個堆損壞錯誤。我再次對C++很陌生,所以我不想試圖解決這個問題,並不小心引入了內存泄漏,所以我想我會問專家。同樣的功能的替代解決方案也很好,因爲這個應用程序最初是用C++ 4編寫的,但現在升級到C++ 11(也簡單解釋了爲什麼這會導致堆損壞會有很大幫助)。

+0

那是生產代碼嗎? – trojanfoe 2013-04-22 15:17:57

+3

使用'std :: string'句號!擺脫所有的指針嘟嘟混雜。 – 2013-04-22 15:18:33

+0

在whilte循環中,它是* psz2 =='0'?或者你的意思是* psz2 ==''0' – Ali 2013-04-22 15:19:16

回答

3

strlen(psz2)正在讀取未初始化的內存,因此可能會超出數組的末尾。這意味着您傳遞給strcpy_s的長度將不可預知,並可能導致您在爲psz1分配的內存末尾之外進行寫入。

假設你的函數的到底是啥(我不充分熟悉CString肯定地說),你可以簡單地改變你的strcpy_s

strcpy_s(psz2, pstr->GetLength() + 1, (const char *) *pstr); 

您可以用win32的遇到的問題在這裏字符串處理函數,可根據UNICODE_UNICODE定義的值在8位和16位字符之間切換。我同意Alok Save和其他人使用std::string會更加清楚和簡單。

+0

'* pstr = psz2;'? CString'支持那個嗎?羅。 – trojanfoe 2013-04-22 15:21:03

+0

@trojanfoe,船長無知我沒有那麼深入的瞭解這個功能。我會相應地重新解釋我的答案。 – simonc 2013-04-22 15:22:06

+0

'psz2 = psz1;'這並不意味着'psz2'指向'psz1',這只是'新'了嗎? – 2013-04-22 15:25:09

2

從MSDN:

errno_t strcpy_s(
    char *strDestination, 
    size_t numberOfElements, 
    const char *strSource 
); 

在這裏,在你的代碼,你是一個未初始化數組上調用strlen,你需要修復它(通過元素的目標緩衝區可存放的最大數量):

strcpy_s(psz2, strlen(psz2), (const char *) *pstr); 
+1

難道你不是隻複製bug strlen(psz2)作爲長度參數strcpy_s()? – harper 2013-04-22 15:28:37

+1

是的,我在這裏顯示了錯誤的確切路線,沒有顯示錯誤修正(作爲練習留給讀者 - 應該很容易,真的)。 – piokuc 2013-04-22 15:31:14