C/C++指針內存分配小細節


char *pc = NULL;

pc = new char[0];

pc[0] = '1';

相信初學者看見上面這段代碼,都會覺得奇怪,new char[n]中的n指定給指針變量分配多少內存空間,而n=0時代表什么呢?

其實上面的程序編譯、運行都是正確的。因為編譯器識別到指定大小為0時,會自動為其分配1BYTE的內存空間。

嘗試過的小伙伴會發現,給p[1]賦值也不會報錯,原因留到后面講*1

但是,此時若想用delete [] p; 去釋放內存空間就會報錯,程序強制中斷,因為編譯器並沒有真正意義上內指針變量分配內存,去釋放肯定是不行的。

這就像對一個成功分配內存的指針變量,連續釋放兩次造成的錯誤,例子見后面*2

好了,馬上看一下成功分配內存的情況是怎么樣的。

char *pc = NULL;

pc = new char[5];

pc[0] = '1';

這里的n=5,意味着給指針變量分配5個BYTE內存空間(因類型為char),當然不管是什么類型,指針變量本身均占4BYTE。

先來看上面遺留的第一個問題*1:此時不但可以給p[0]到p[4]賦值,還可以給后面的地址賦值,如p[5],p[10]等。

這就是C/C++完美之余的一個歷史遺留缺陷,不進行越界檢查。

導致編譯沒有任何問題,運行階段有時一不小心也察覺不出,這就要求程序員養成良好的習慣:new后面必出現delete。

若我們在給p[5]或之后的地址賦過值,在運行到delete [] p;語句時,會報錯,程序強制中斷。錯誤原因如提示的信息:damage:after normal block。

這就是上面遺留的第二個問題*2:對同一個指針變量指向的內存釋放兩次,與釋放一個沒有成功分配內存或引用越界的指針變量類似,都是不允許的。

還有一個值得注意的地方:若new時n>0,delete后只是釋放了原來內存地址中對應的值,指針變量仍然指向該內存地址,即:

仍可以賦值、取值進行運算,只是若沒有重新賦值,取出的值為不確定值,換句話說就是,p成了傳說中的野指針。

所以,這又是一個要求養成良好習慣的地方,看文章開頭的地方,聲明一個指針但未分配內存空間時,最好將其置為NULL。

這樣做有兩個好處:1、方便后面進行判斷,if(!P){...}表示無內存分配,若當初沒有將其置為NULL,則!p為真也代表不了什么;

2、在delete后,重新分配內存之前,將其置回為NULL,避免其成為野指針。

而對於malloc與free,情況類似,有興趣的小伙伴可以嘗試下。

剛開始學習這一塊,有哪里不對的地方歡迎大家指出,謝謝!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM