2012-12-28 34 views
0

我的代碼:因無效鑄造造成的堆損壞?

unsigned char *myArray = new unsigned char[40000]; 

char pixelInfo[3]; 
int c = 0; 
while(!reader.eof()) //reader is a ifstream open to a BMP file 
{ 
    reader.read(pixelInfo, 3); 
    myArray[c] = (unsigned char)pixelInfo[0]; 
    myArray[c + 1] = (unsigned char)pixelInfo[1]; 
    myArray[c + 2] = (unsigned char)pixelInfo[2]; 
    c += 3; 
} 
reader.close(); 

delete[] myArray; //I get HEAP CORRUPTION here 

一些測試後,我發現它是由while循環中投造成的,如果我使用一個符號的字符數組myArray我不明白的錯誤,但我必須使用unsigned char代碼的其餘部分。 將pixelInfo轉換爲無符號字符也會產生相同的錯誤。

有沒有解決這個問題的方法?

+3

'!eof()'條件的詛咒返回。 –

+1

而你是**確定**你沒有寫過數組的邊界? – StoryTeller

+0

好吧,你是幾內亞豬。你能告訴我們所有的*爲什麼*你認爲'!reader.eof()'是一個合理的條件?請詳細解釋你的推理,或者你的信息來源。看起來,每個使用C++的人都會犯這個錯誤,我真的很想知道這個普遍的誤解是從哪裏來的。 –

回答

1

這是你應該做的:

reader.read((char*)myArray, myArrayLength); /* note, that isn't (sizeof myArray) */ 

if (!reader) { /* report error */ } 

如果有環路內側處理事情,然後

int c = 0; 
while (c + 2 < myArraySize) //reader is a ifstream open to a BMP file 
{ 
    reader.read(pixelInfo, 3); 
    myArray[c] = (unsigned char)pixelInfo[0]; 
    myArray[c + 1] = (unsigned char)pixelInfo[1]; 
    myArray[c + 2] = (unsigned char)pixelInfo[2]; 
    c += 3; 
} 

嘗試後您閱讀」最後的結果並不是問題 - 你會在數組的其餘部分得到垃圾,但最後你可以處理它。

假設您的數組足夠大以容納整個文件邀請緩衝區損壞。包含精心製作的不正確元數據的圖像文件的緩衝區溢出攻擊是衆所周知的。

不要依賴計算出的緩衝區大小中的整個文件內容。

+0

該代碼示例不適用於我,因爲我編寫了一個簡化版本,實際上我在循環中更改了值。 但是,有關緩衝區溢出的信息非常感謝,我將努力使其更安全。 – Danicco

+0

@Danicco:那麼,你可以寫你的循環爲'while(c

+0

這就是我所做的,現在它工作得非常好,謝謝你的額外信息! – Danicco

0

reader.eof()只會告訴你前一次讀取是否到達文件末尾,這會導致最終迭代寫入數組末尾。你想要的是檢查當前讀取是否結束文件。更改while環路:

while(reader.read(pixelInfo, 3)) //reader is a ifstream open to a BMP file 
{ 
    // ... 
} 
+0

不,「檢查當前讀取是否結束文件」並不是他想要的。當他碰到像素陣列的末端時停下來是他需要的。 –

0

請注意,您一次讀取3個字節。如果字節總數不能被3整除(不是3的倍數),那麼只有部分pixelInfo數組實際上會填充正確的數據,這可能會導致程序出錯。你可以試試下面一塊未測試的代碼。

while(!reader.eof()) //reader is a ifstream open to a BMP file 
{ 
    reader.read(pixelInfo, 3); 
    for (int i = 0; i < reader.gcount(); i++) { 
     myArray[c+i] = pixelInfo[i]; 
    } 
    c += 3; 
} 

您的代碼不會遵循cplusplus.com的文檔非常好,因爲EOF位將不完整讀取後進行設置,以便該代碼將您的最後一次讀取後終止然而,當我是你的問題的可能原因之前提到的是因爲您將可能的垃圾數據分配給堆,因爲如果未讀取3個字節,則可能不需要設置pixelInfo [x]。

+0

仍然濫用'eof()',並且仍然愉快地溢出數組並且破壞堆。 –

+0

@本Voigt我不知道我是如何濫用eof。它檢查是否設置了哪個讀取在發生故障時進行。在讀取不完整的情況下,數組仍然會被分配,並在下一次迭代時退出。如果數組完成讀取最後3個字節,則下一次迭代將嘗試讀取另外3個字節,它將失敗並導致下一次eof檢查失敗。 –

+0

回答我自己的問題:http://www.parashift.com/c++-faq-lite/istream-and-eof.html –