序言
C/C++中的指針讓程序員有了更多的靈活性,但它同時也是一把雙刃劍,如果用的不好,則會讓你的程序出現(xiàn)各種各樣的問題,有人說,C/C++程序員有一半的工作量是花在處理由指針引起的bug上,可想而知,指針中包含的陷阱是多么可怕。既然如此,我們在編寫代碼的時候就應(yīng)該把好關(guān)。
要想在編寫代碼的時候盡可能避免指針帶來的問題,就需要知道不恰當?shù)氖褂弥羔樀降讜l(fā)哪些問題, 又該如何去避免它?下面一起來總結(jié)在使用指針時容易遇到的問題。
【文章福利】:小編推薦自己的C語言交流群:967051845!整理了一些個人覺得比較好的學(xué)習(xí)書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦!~
1.避免內(nèi)存泄露
程序在運行的時候需要內(nèi)存,同時我們也知道內(nèi)存是有限的,是計算機特別寶貴的資源,對于使用完的內(nèi)存,應(yīng)當及時的歸還給操作系統(tǒng)。
在C/C++中,如果是棧上的內(nèi)存(比如說函數(shù)中的局部非靜態(tài)變量),在使用完之后,操作系統(tǒng)會幫我們自動回收;但是如果是通過動態(tài)分配得到的堆上的內(nèi)存,需要我們手動釋放。
如果我們在程序中忘了釋放這些動態(tài)內(nèi)存,而程序又是會持續(xù)運行的服務(wù)進程,會導(dǎo)致內(nèi)存占用越來越高,輕者致殘影響系統(tǒng)性能,重者致命導(dǎo)致進程崩潰。
總之一句話,不再用到的內(nèi)存沒有釋放,就叫做內(nèi)存泄露,內(nèi)存泄露的問題很嚴重。
看幾個內(nèi)存泄露的案例:
在C/C++中,通過動態(tài)內(nèi)存分配函數(shù)或者new運算符分配的動態(tài)內(nèi)存在使用完之后需要手動釋放。否則會造成內(nèi)存泄露。

建議:代碼編寫時注意malloc/free, new/delete成對使用
即使在malloc/new后顯示調(diào)用了free/delete釋放內(nèi)存,但是 由于異??赡軙?dǎo)致釋放內(nèi)存的free/delete語句得不到執(zhí)行,也會發(fā)生內(nèi)存泄露 ,下面的例子就是這種情況。

從運行結(jié)果來看,類的析構(gòu)函數(shù)沒有被執(zhí)行,可推知delete語句并沒有得到執(zhí)行。
有人會說,這還不簡單,直接在catch語句的cout << "Something has gone wrong" << endl;下面之后加個delete t不就行了?
沒錯,這只是個幾十行代碼的測試程序,你可能一下就看出問題了,但是如果你面對的是一個龐大的工程時候,我想你內(nèi)心一定是好崩潰的。還有更好的辦法來解決這種問題,就是智能指針。
建議:C++代碼代碼中多注意使用智能指針
2.不要使用野指針
野指針也叫懸掛指針,是指向“垃圾”內(nèi)存的指針,使用“野指針”會讓程序出現(xiàn)不確定的行為。
注意,野指針不是NULL指針, 它比NULL指針更容易犯錯,因為它不能通過形如 if (NULL == p)的判斷語句來預(yù)防,只能我們自己在寫代碼時多注意。
指針p被free或者delete之后,沒有置為NULL,讓人誤以為p是個合法的指針,事實上free或delete只是把指針所指的內(nèi)存給釋放掉,但是指針的值還是這塊內(nèi)存的地址,只不過這塊內(nèi)存已經(jīng)被回收了不能被該進程再使用,下面的例子就是一個典型的使用野指針的案例。


建議:free或delete之后將相應(yīng)的指針設(shè)置為NULL
在創(chuàng)建指針變量p時忘了初始化,p的值是個隨機的垃圾值,此時讀寫該指針都是危險的,程序會產(chǎn)生不確定的行為
看看下面的例子,原本是想將fun函數(shù)中的變量i的地址返回給p,用p訪問這個變量,這個打印出*p是32767,并不是變量i的值8。像這種bug,一旦在大的項目中出現(xiàn)是很難定位的。


建議:不要在函數(shù)中返回局部變量的地址,如果代碼的邏輯非要是一個局部變量的地址,那么該局部變量一定要申明為static類型,因為static變量的生存期是整個程序運行期間
3.不要使用NULL指針
大家都知道,在程序中不能使用NULL指針,但是如果不注意,程序中還是有可能在你的意料之外就使用到NULL指針,下面看兩個比較容易出問題的例子。
動態(tài)內(nèi)存分配函數(shù)分配內(nèi)存的時,有可能會分配失敗,此時返回NULL

從程序運行結(jié)果來看,malloc分配失敗返回NULL賦給p,再通過p訪問其所指向的0地址內(nèi)存內(nèi)容時,出現(xiàn)"Segmentation fault"錯誤。
建議:在使用內(nèi)存分配函數(shù)分配內(nèi)存的時候,應(yīng)該用i f(p==NULL) 或if(p!=NULL)進行防錯處理。
此外,在含有指針參數(shù)的函數(shù),也是有可能會誤用到NULL指針,當調(diào)用該函數(shù)時傳遞的指針是個空指針,如果沒有if(p!=NULL) 的判斷條件,那么在后面使用指針的時候麻煩就大了,下面的例子就是這種情況


建議:對于含有指針參數(shù)的函數(shù),也應(yīng)當在函數(shù)入口處用if(p==NULL) 或if(p!=NULL)進行防錯處理。
最后,如果你想學(xué)C/C++可以找我一起探討編程 !
如果覺得學(xué)習(xí)資料難找的話,可以添加小編的C語言/C++交流群:967051845!學(xué)習(xí)資料已經(jīng)共享在群里了,期待你的加入~
祝所有程序員都能夠走上人生巔峰,讓代碼將夢想照進現(xiàn)實,非常適合新手學(xué)習(xí),有不懂的問題可以隨時問我,工作不忙的時候希望可以給大家解惑