Debug Assertion Failed _CrtlsValidHeapPointer(block) realloc堆引发的错误
應用場景
二級指針的應用中堆的處理
問題描述:
realloc后出現堆錯誤
#include"algorithm.h"//數組插入元素 int insert(int **pp ,int &n,int tmp, int pos) {if (0 <= pos&&pos <= n){int *po = *pp;//保存 舊一級指針int *pn=NULL;//創建一級指針作為新地址//ppcout << "&pp" << "\t" <<&pp<< endl;cout << "pp" << "\t" << pp << endl;cout << "*pp" << "\t" << *pp << endl;cout << "**pp" << "\t" << **pp << endl;printf("\n");//pocout << "&po" << "\t" <<&po << endl;cout << "po" << "\t" << po << endl;cout << "*po" << "\t" << *po << endl;printf("\n");n =20;pn = (int *)realloc(po, n*sizeof(int));//pncout << "&pn" << "\t" << &pn << endl;cout << "pn" << "\t" << pn << endl;cout << "*pn" << "\t" << *pn << endl;printf("\n");pp = &pn;//pp更新后cout << "&pp" << "\t" << &pp << endl;cout << "pp" << "\t" << pp << endl;cout << "*pp" << "\t" << *pp << endl;cout << "**pp" << "\t" << **pp << endl;printf("\n");//int i = n;//while (i > pos)//{// p[i--] = p[i - 1];//從后往前騰出位置//}//p[pos] = tmp;free(po);return 0;}elsereturn -1; }int main() {int n = 9, t, pos = 0;int *p = (int *)malloc(n*sizeof(int));int **pp = &p;scan_arr(p, n);scanf("%d", &t);pos = 6;insert(pp, n, t, pos);}運行結果:
原因分析:
報錯Expression:_CrtlsValidHeapPointer(block) :這是無效的堆指針,也就是存在堆錯誤。
free()/delete在一塊堆內存的時候會檢查堆頭,如果堆頭有異常,就報堆錯誤。
對分配的指針不要進行賦值操作了,否則賦值后,再進行free()找不到原來的指針,也會報錯。
realloc(p,n)
先判斷當前的指針是否有足夠的連續空間,如果有,擴大mem_address指向的地址,并且將mem_address返回,如果空間不夠,先按照newsize指定的大小分配空間,將原有數據從頭到尾拷貝到新分配的內存區域,而后釋放原來mem_address所指內存區域(注意:原來指針是自動釋放,不需要使用free),同時返回新分配的內存區域的首地址。即重新分配存儲器塊的地址。
解決方案:
因為realloc重新分配后,po的會自動釋放,因此不要重復釋放,去掉free(po)便可。
...n = 100;pn = (int *)realloc(po, n*sizeof(int));if (pn)//成功分配 {//舊指針最好清零po = NULL;//若改為free(po)釋放舊指針會導致指針懸空!!! //free(po);//錯誤cout << "po" << "\t" << po << endl; cout << endl;}else{printf("內存不足\n");return NULL;}//pncout << "&pn" << "\t" << &pn << endl;cout << "pn" << "\t" << pn << endl;cout << "*pn" << "\t" << *pn << endl;printf("\n");...若無 po=NULL;而是free(po);則由于po是個野指針(po指向的塊其實已被realloc自動釋放,只是po并未清零),這時候對po的操作都是對野指針的操作,沒有意義并且可能破壞其他內存;
當n=20較小時,realloc采用第一種分配方式,得到結果如圖,雖然堆沒有報錯,但是*pn不正確,說明pn的塊在free(po)的時候沖掉了
當n=100較大時,realloc采用第二種分配方式,運行報錯,free(po)會檢查堆頭,發現po的堆被(realloc自動)釋放了,產生堆頭錯誤
?
因此要使用realloc要特別注意應先判斷返回值,再對舊指針清零。
簡而言之:free()釋放內存并不會將指針置零,可以通過手動置零以免產生野指針。
總結
以上是生活随笔為你收集整理的Debug Assertion Failed _CrtlsValidHeapPointer(block) realloc堆引发的错误的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: (Matlab问题解决)运行matlab
- 下一篇: PyTorch框架学习五——图像预处理t