日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Debug Assertion Failed _CrtlsValidHeapPointer(block) realloc堆引发的错误

發(fā)布時間:2024/7/23 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Debug Assertion Failed _CrtlsValidHeapPointer(block) realloc堆引发的错误 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

應(yīng)用場景

二級指針的應(yīng)用中堆的處理

問題描述:

realloc后出現(xiàn)堆錯誤

#include"algorithm.h"//數(shù)組插入元素 int insert(int **pp ,int &n,int tmp, int pos) {if (0 <= pos&&pos <= n){int *po = *pp;//保存 舊一級指針int *pn=NULL;//創(chuàng)建一級指針作為新地址//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);}

運行結(jié)果:

原因分析:

報錯Expression:_CrtlsValidHeapPointer(block) :這是無效的堆指針,也就是存在堆錯誤。

free()/delete在一塊堆內(nèi)存的時候會檢查堆頭,如果堆頭有異常,就報堆錯誤。
對分配的指針不要進行賦值操作了,否則賦值后,再進行free()找不到原來的指針,也會報錯。

realloc(p,n)
先判斷當(dāng)前的指針是否有足夠的連續(xù)空間,如果有,擴大mem_address指向的地址,并且將mem_address返回,如果空間不夠,先按照newsize指定的大小分配空間,將原有數(shù)據(jù)從頭到尾拷貝到新分配的內(nèi)存區(qū)域,而后釋放原來mem_address所指內(nèi)存區(qū)域(注意:原來指針是自動釋放,不需要使用free),同時返回新分配的內(nèi)存區(qū)域的首地址。即重新分配存儲器塊的地址。

解決方案:

因為realloc重新分配后,po的會自動釋放,因此不要重復(fù)釋放,去掉free(po)便可。

...n = 100;pn = (int *)realloc(po, n*sizeof(int));if (pn)//成功分配 {//舊指針最好清零po = NULL;//若改為free(po)釋放舊指針會導(dǎo)致指針懸空!!! //free(po);//錯誤cout << "po" << "\t" << po << endl; cout << endl;}else{printf("內(nèi)存不足\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并未清零),這時候?qū)o的操作都是對野指針的操作,沒有意義并且可能破壞其他內(nèi)存;
當(dāng)n=20較小時,realloc采用第一種分配方式,得到結(jié)果如圖,雖然堆沒有報錯,但是*pn不正確,說明pn的塊在free(po)的時候沖掉了

當(dāng)n=100較大時,realloc采用第二種分配方式,運行報錯,free(po)會檢查堆頭,發(fā)現(xiàn)po的堆被(realloc自動)釋放了,產(chǎn)生堆頭錯誤

?

因此要使用realloc要特別注意應(yīng)先判斷返回值,再對舊指針清零。

簡而言之:free()釋放內(nèi)存并不會將指針置零,可以通過手動置零以免產(chǎn)生野指針。

總結(jié)

以上是生活随笔為你收集整理的Debug Assertion Failed _CrtlsValidHeapPointer(block) realloc堆引发的错误的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。