HEAP CORRUPTION DETECTED:after Normal block錯誤方法解決
阿新 • • 發佈:2020-10-23
一:問題描述:
出現的問題如下:
二:問題產生的原因說明
該問題發生於操作堆記憶體的時候。產生該問題的原因是:你實際使用的記憶體大小超出了你實際申請的記憶體大小,在釋放記憶體的時候就會發生該問題。
舉個例子:假如你申請了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錯誤。
解決方案:當申請堆記憶體空間的時候,申請的空間大小一定要大於等於實際上使用的記憶體空間大小。