【學習】動態記憶體分配導致的堆溢位問題:Critical error detected c0000374
阿新 • • 發佈:2021-12-05
今天在寫霍夫曼樹的例程的時候遇到了一個較為棘手的錯誤,在這裡記錄一下
如圖所示,在執行
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; }
(由於vs的intelliSence比較智慧,此處通過RangeChecks即發現了對堆的越界訪問:
0x77E0A37B (ntdll.dll) (CppHomeworkFramework.exe 中)處有未經處理的異常: RangeChecks 檢測程式碼檢測到超出範圍的陣列訪問。
而觀察這段程式,其實這段程式已經成功造成了堆溢位,其關鍵在於對陣列的非法下標訪問。這個下標(自1開始)都沒有申請。