[學習]動態內存分配導致的堆溢出問題:Critical error detected c0000374


今天在寫霍夫曼樹的例程的時候遇到了一個較為棘手的錯誤,在這里記錄一下

如圖所示,在運行

HT.tree = (HuffmanTree<int>::HTNode*)malloc((m + 1) * sizeof(HuffmanTree<int>::HTNode));

時vs給出了一個奇怪的錯誤,這個錯誤沒有報錯提示,在繼續運行之后繼續顯示

這里的“堆”代表的是

堆:操作系統有一個記錄空閑內存地址的鏈表,當系統收到程序的申請時,會遍歷該鏈表,尋找第一個空間大於所申請空間的堆結點,然后將該結點從空閑結點鏈表中刪除,並將該結點的空間分配給程序,另外,對於大多數系統,會在這塊內存空間中的首地址處記錄本次分配的大小,這樣代碼中的delete語句才能正確的釋放本內存空間。 另外由於找到的堆結點的大小不一定正好等於申請的大小,系統會自動的將多余的那部分重新放入空閑鏈表中。
www.cnblogs.com/George1994/p/6399895.html

換句話說,操作系統給客戶程序用於動態申請和釋放的空間稱為堆。

此處的“堆損壞”就是此鏈表內部的數據檢查不通過,換句話說,里面的未分配的空間上的值被修改了。由於堆作為鏈表可以隨機訪問,因此對於其訪問域的限制便沒有那么完善,因而可能在未申請的情況下直接訪問某些不應該訪問的堆的值,此時操作系統分配空閑空間的時候檢查不通過,從而導致堆損壞。

例如下述程序:

int* test_heap_alloc()
{
	int* pTable = new int(256); // 申請一個int結構體變量,初始值為256;
	for (int i = 0; i < 256; i++)
		pTable[i] = i;
	return pTable;
}
int main(int argc, char** argv) {

	test_heap_alloc();
	return 0;
}

https://blog.csdn.net/chunyexiyu/article/details/120233683

(由於vs的intelliSence比較智能,此處通過RangeChecks即發現了對堆的越界訪問:

0x77E0A37B (ntdll.dll) (CppHomeworkFramework.exe 中)處有未經處理的異常: RangeChecks 檢測代碼檢測到超出范圍的數組訪問。

而觀察這段程序,其實這段程序已經成功造成了堆溢出,其關鍵在於對數組的非法下標訪問。這個下標(自1開始)都沒有申請。


因此解決方案很簡單:檢查已有代碼,查看是否存在上述的越界操作。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM