1. 程式人生 > 實用技巧 >HEAP CORRUPTION DETECTED:after Normal block錯誤方法解決

HEAP CORRUPTION DETECTED:after Normal block錯誤方法解決

一:問題描述:

出現的問題如下:

二:問題產生的原因說明

該問題發生於操作堆記憶體的時候。產生該問題的原因是:你實際使用的記憶體大小超出了你實際申請的記憶體大小,在釋放記憶體的時候就會發生該問題。

舉個例子:假如你申請了3個位元組的堆記憶體空間 char *ptr = (char *)malloc(sizeof(char)*3);

但是你在使用的時候使用了4個位元組,char *t1 = "abc";// 注意末尾有一個'\0'字元

strcpy(ptr, buf);// 拷貝函式預設會在末尾新增一個'\0'字元,在此處你僅僅申請了3個位元組的空間,但你實際使用的空間為4個位元組

在往ptr指向的3個位元組的堆記憶體空間,寫入超過一個位元組的內容時, vs2010中的編譯器並不會報錯, 但是為後面的記憶體釋放埋下個巨大的隱患。

此後當你在釋放ptr指向的記憶體時,由於你使用了超過申請大小的記憶體空間,導致記憶體不能正確釋放,就會發生上面的問題。

三:舉例

有問題程式碼如下:

 1 #define _CRT_SECURE_NO_WARNINGS
 2 #include <iostream>
 3 using namespace std;
 4 int main()
 5 {
 6     const char* t1 = "
abc"; 7 cout << sizeof(t1) << endl; // 4 8 9 // 申請內 10 int memSize = 3; 11 char* ptr = (char*)malloc(sizeof(char) * memSize); // 僅僅申請了3個位元組的堆記憶體空間 12 // 初始化記憶體 13 memset(ptr, 0, memSize); 14 // 拷貝內容 15 strcpy(ptr, t1); // strcpy拷貝時末尾預設會新增一個'\0'字元, 所以實際使用的記憶體空間為4個位元組,超出了申請的記憶體空間大小,為後來的記憶體釋放埋下了巨大的隱患
16 17 cout << ptr << endl; 18 19 if (ptr != NULL) 20 { 21 free(ptr); 22 ptr = NULL; 23 } 24 25 system("pause"); 26 return 0; 27 }

上面的程式碼執行後就會出現下面的問題

正確程式碼:

 1 #define _CRT_SECURE_NO_WARNINGS
 2 #include <iostream>
 3 using namespace std;
 4 int main()
 5 {
 6     const char* t1 = "abc";
 7     cout << sizeof(t1) << endl; // 4
 8 
 9     // 申請內
10     //int memSize = 3;// 申請記憶體的大小必須與實際使用的記憶體大小一致
11     int memSize = 4;// 實際使用的記憶體大小為4個位元組,那麼申請記憶體必須大於等於實際使用的記憶體。
12     char* ptr = (char*)malloc(sizeof(char) * memSize);  
13     // 初始化記憶體
14     memset(ptr, 0, memSize);
15     // 拷貝內容
16     strcpy(ptr, t1);  
17 
18     cout << ptr << endl;
19 
20     if (ptr != NULL)
21     {
22         free(ptr);
23         ptr = NULL;
24     }
25 
26     system("pause");
27     return 0;
28 }

四:總結

當實際使用的記憶體大小超過了申請記憶體空間大小時,在以後釋放記憶體的時候就會引發HEAP CORRUPTION DETECTED:after Normal block錯誤。

解決方案:當申請堆記憶體空間的時候,申請的空間大小一定要大於等於實際上使用的記憶體空間大小。