c++指針傳遞導(dǎo)致的重復(fù)釋放問(wèn)題解決
first
先看這段代碼,有多個(gè)地方都會(huì)釋放 pPointer 的對(duì)象空間,但是為了防止重復(fù)釋放,在第二次釋放時(shí)做了判空處理;不為空才釋放;
#include <iostream>
using namespace std;
// 釋放內(nèi)存
void release(int *pPointer){
delete pPointer;
pPointer = nullptr;
}
int main() {
int *pPointer = new int();
// 釋放
release(pPointer);
if(pPointer) delete pPointer;
return 0;
}
執(zhí)行結(jié)果如下, 報(bào)錯(cuò)了,告訴我執(zhí)行了2次free函數(shù),也就是重復(fù)釋放了;這是怎么回事呢? 我明明有做判空?。?/p>
free(): double free detected in tcache 2 Process finished with exit code 134
原因
原來(lái);在調(diào)用release函數(shù)時(shí),傳入的指針變量,實(shí)際是經(jīng)過(guò)了拷貝的;不信是吧,我們來(lái)做個(gè)實(shí)驗(yàn),在main函數(shù)和release函數(shù)都打印下 pPointer 對(duì)象的地址,代碼如下
void release(int *pPointer){
printf("release pPointer:%x\n",&pPointer); // 打印pPointer指針對(duì)象的地址
delete pPointer;
pPointer = nullptr;
}
int main() {
int *pPointer = new int();
printf("main pPointer:%x\n",&pPointer); // // 打印pPointer指針對(duì)象的地址
// 釋放
release(pPointer);
if(pPointer)delete pPointer;
return 0;
}
執(zhí)行結(jié)果如下, 可以看到 2個(gè)指針地址是不同的,這也就證明了,在傳參的過(guò)程中是發(fā)生了拷貝的;release 函數(shù)中的 pPointer 對(duì)象和main函數(shù)中的 pPointer 對(duì)象并不是同一個(gè)對(duì)象,只是他們都指向了同一塊內(nèi)存。
main pPointer:f22d1fb0 release pPointer:f22d1f98 free(): double free detected in tcache 2 Process finished with exit code 134
所以,他們的時(shí)間線如下:
- 在 release 函數(shù)內(nèi)釋放 pPointer, 并將 pPointer 賦值為 nullptr,此時(shí),pPointer 所指向的內(nèi)存塊已經(jīng)被釋放,
- 但是只是將 release 函數(shù)內(nèi)的 pPointer 變量賦值為 nullptr,main函數(shù)中 pPointer 還是指向原來(lái)的地址;因?yàn)橹羔樦赶虻膬?nèi)存塊已被釋放,此時(shí) main 函數(shù)中 pPointer 就是個(gè)野指針;
- 當(dāng)指執(zhí)行到
if(pPointer) delete pPointer;代碼時(shí),pPointer 并不是空指針 nullptr ,它還指向原來(lái)的地址,所以判斷if(pPointer)的結(jié)果為真(true),然后會(huì)執(zhí)行delete pPointer;,但是原來(lái)地址的空間已經(jīng)在release函數(shù)釋放了,執(zhí)行delete pPointer;后就會(huì)報(bào)錯(cuò):double free detected in tcache 2;
解決
方案一 :使用指針引用
將release函數(shù)的參數(shù)改為指針引用,如下,注意看,*后面多了個(gè)&符號(hào),其他代碼無(wú)需改動(dòng)
void release(int *& pPointer){
delete pPointer;
pPointer = nullptr;
}
再次執(zhí)行后,就不會(huì)報(bào)錯(cuò)了, 且main函數(shù)和release函數(shù)的 pPointer 對(duì)象地址也是相同的
main pPointer:c12d0580 release pPointer:c12d0580 Process finished with exit code 0
方案二:使用二級(jí)指針
將release函數(shù)的參數(shù)改為二級(jí)指針,也能解決問(wèn)題,如下
void release(int **pPointer){
printf("release pPointer:%x\n",pPointer);
delete *pPointer; // 這里需要解引用
*pPointer = nullptr; // 這里需要解引用
}
int main() {
int *pPointer = new int();
printf("main pPointer:%x\n",&pPointer);
// 釋放 - 需要加上取地址符號(hào)
release(&pPointer);
if(pPointer)delete pPointer;
return 0;
}
執(zhí)行后結(jié)果如下
main pPointer:d2699950
release pPointer:d2699950
Process finished with exit code 0
到此這篇關(guān)于c++指針傳遞導(dǎo)致的重復(fù)釋放問(wèn)題解決的文章就介紹到這了,更多相關(guān)c++指針傳遞導(dǎo)致重復(fù)釋放內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- C++函數(shù)三種傳參形式(指針傳遞、引用傳遞、值傳遞)
- c++指針參數(shù)傳遞和引用參數(shù)傳遞的區(qū)別解析
- C++?指針傳遞的作用小結(jié)
- C++成員函數(shù)如何當(dāng)作回調(diào)函數(shù)同時(shí)傳遞this指針
- C++之值傳遞&指針傳遞&引用傳遞的示例詳解
- C++中引用傳遞與指針傳遞的區(qū)別(面試常見(jiàn))
- 淺析C++的引用與const指針與各種傳遞方式
- java及C++中傳值傳遞、引用傳遞和指針?lè)绞降睦斫?/a>
- c++傳遞函數(shù)指針和bind的示例
- C++指針作為函數(shù)的參數(shù)進(jìn)行傳遞時(shí)需要注意的一些問(wèn)題
相關(guān)文章
C++基礎(chǔ)入門教程(一):基礎(chǔ)知識(shí)大雜燴
這篇文章主要介紹了C++基礎(chǔ)入門教程(一):基礎(chǔ)知識(shí)大雜燴,本文講解了注釋、頭文件、命名空間等內(nèi)容,需要的朋友可以參考下2014-11-11
Cocos2d-x保存用戶游戲數(shù)據(jù)CCUserDefault類使用實(shí)例
這篇文章主要介紹了Cocos2d-x保存用戶游戲數(shù)據(jù)CCUserDefault類使用實(shí)例,需要的朋友可以參考下2014-09-09
c++重載運(yùn)算符時(shí)返回值為類的對(duì)象或者返回對(duì)象的引用問(wèn)題
這篇文章主要介紹了c++重載運(yùn)算符時(shí)返回值為類的對(duì)象或者返回對(duì)象的引用問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11
復(fù)數(shù)乘法中的結(jié)構(gòu)體賦值實(shí)現(xiàn)代碼
復(fù)數(shù)乘法中的結(jié)構(gòu)體賦值實(shí)現(xiàn)代碼。需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2013-10-10

