想必大家都知道C語言中動態(tài)開辟內存之后,必須要釋放內存,來防止內存泄露。也就是malloc之后,必須要free。正所謂”有借有還,再借不難”, 不少同學會問為什么釋放指針后,指向這塊內存的指針的值不變呢,我們今天為大家揭秘。
首先,我們用malloc開辟一個內存,用strcpy拷貝一串字符串,然后釋放掉,通過斷點調試進行觀察!
下圖可以看到,在VC6編譯環(huán)境下,觀察指針p的指針所指向的內容已經被strcpy后改變
下一步free函數(shù),我們選擇F11單步介入觀察,幸運的是在VC6中可以看到源代碼,如下圖,會進入到DBGHEAP.c文件中,會調用_free_dbg函數(shù),繼續(xù)F11介入觀察代碼
多次單步之后,我們可以看到一個memset函數(shù),那么F10執(zhí)行這memset,觀察P指向的內容,果然不出我們所料:
0x00970e38處的內容已經被0xDD覆蓋,如下圖紅色字部分。
這里重點觀察了,這個memset函數(shù)我們應該很熟悉,第二個參數(shù)即為要重置的內容,這里我們可以轉到定義 處,或者搜索第二個參數(shù)_bDeadLandFill,可以看到有如下定義, 為0xDD
怎么樣,大家看到這里應該明白了吧!
我們這里是VC6編譯器下的環(huán)境,也有部分同學反映free之后內容并未消失,這里我們分析可能是部分編譯器free函數(shù)實現(xiàn)原理不同,歡迎大家自行嘗試,并與我們交流。
而關于free之后,p的之后為何沒有改變,仍然還是這個原先堆空間的這個地址,原因在于free函數(shù)僅僅是將malloc申請的內存釋放回去,所謂的釋放也就是告訴編譯器,這塊內存已經使用完畢,可以收回了。但指針所指向的內存值,并不會發(fā)生改變。就可以比方說,你租了一套房子,到期后,房子收回歸還房東,而此時你可能還拿著房子的鑰匙,這個時候你雖然可以繼續(xù)訪問這個房子(內存),但已經不屬于你,是非法的。也可能有新的租客入駐更改房子的內置,也可能還是這個樣子。取決于不同的房東(編譯器)和租客(內容)。
這就是free釋放內存后,指針內地址仍然存在,但有時還可以訪問,有時候訪問輸出亂碼或輸出其他值的原因。
怎么樣,大家明白了嗎?
有任何問題,或新的發(fā)現(xiàn),歡迎聯(lián)系我們!
C語言研究中心(www.sztianhecheng.cn)