更新時間:2020-01-16 來源:黑馬程序員 瀏覽量:
C/C++運(yùn)行高效,不管是操作系統(tǒng)內(nèi)核還是對性有要求的程序(比如游戲引擎)都要求使用C/C++來編寫,其實C/C++強(qiáng)大的一點(diǎn)在于能夠使用指針自由地控制內(nèi)存的使用,適時的申請內(nèi)存和釋放內(nèi)存,從而做到其他編程語言做不到的高效地運(yùn)行。但是內(nèi)存管理是一把雙刃劍,用好了削鐵如泥,用不好自斷一臂。在申請堆上內(nèi)存使用完之后中如果做不到適時有效的釋放,那么就會造成內(nèi)存泄露,久而久之程序就會將系統(tǒng)內(nèi)存耗盡,導(dǎo)致系統(tǒng)運(yùn)行出問題。就如同你每天跑去圖書館借一打書籍而不還,直到圖書館倒閉為止。
C語言中申請內(nèi)存和釋放內(nèi)存的方法是使用 malloc和free。
C++中能兼容C,所以也能使用malloc和free,面向?qū)ο蟮那闆r下使用的則是new和delete,能夠自動執(zhí)行構(gòu)造函數(shù)和析構(gòu)函數(shù)。
在Linux平臺,我們可以使用valgrind命令檢測C/C++程序是否內(nèi)存泄露。
02. valgrind安裝
debian/ubuntu下安裝方法:
deng@itcast:~$ sudo apt install valgrind安裝好valgrind工具之后,下面來看看valgrind的幾個應(yīng)用場景。
redhat/centos下安裝方法:
03. 使用未初始化的內(nèi)存
程序中我們定義了一個指針p,但并未給他分配空間,但我們卻使用它了。
程序示例:
valgrind檢測出到我們的程序使用了未初始化的變量。
04. 使用野指針
p所指向的內(nèi)存被釋放了,p變成了野指針,但是我們卻繼續(xù)使用這片內(nèi)存。
程序示例:
valgrind檢測到我們使用了已經(jīng)free的內(nèi)存,并給出這片內(nèi)存是哪里分配和哪里釋放的。
05. 動態(tài)內(nèi)存越界訪問
我們動態(tài)地分配了一片連續(xù)的存儲空間,但我們在訪問個數(shù)組時發(fā)生了越界訪問。
程序示例:
valgrind檢測出越界信息如下。
注意:
valgrind不檢查非動態(tài)分配數(shù)組的使用情況。
06. 分配空間后沒有釋放
內(nèi)存泄漏的原因在于我們使用free或者new分配空間之后,沒有使用free或者delete釋放內(nèi)存。
程序示例:
valgrind的記錄顯示上面的程序用了1次malloc,卻調(diào)用了0次free。
可以使用--leak-check=full進(jìn)一步獲取內(nèi)存泄漏的信息,比如malloc具體行號。
07. 不匹配使用delete或者free
一般我們使用malloc分配的空間,必須使用free釋放內(nèi)存。使用new分配的空間,使用delete釋放內(nèi)存。
程序示例:
不匹配地使用malloc/new/new[] 和 free/delete/delete[]則會被提示mismacth
08. 兩次釋放同一塊內(nèi)存
一般情況下,內(nèi)存分配一次,只釋放一次。如果多次釋放,可能會出現(xiàn)double free。
程序示例:
多次釋放同一內(nèi)存,出現(xiàn)非法釋放內(nèi)存。
09. 總結(jié)
內(nèi)存泄露問題非常難定位,對于小工程項目來說,簡單去檢查代碼中new和delete的匹配對數(shù)就基本能定位到問題,但是一旦代碼量上升到以萬單位時,僅靠肉眼檢查來定位問題那就非常困難了,所以我們需要利用工具幫助我們找出問題所在。在Linux系統(tǒng)下內(nèi)存檢測工具首推Valgrind,一款非常好用的開源內(nèi)存管理工具。Valgrind其實是一個工具集,內(nèi)存錯誤檢測只是它眾多功能的一個,但我們用得最多的功能正是它——memcheck。推薦了解黑馬程序員C++培訓(xùn)課程。
總之,valgrind工具可以檢測下列與內(nèi)存相關(guān)的問題 :
· 未釋放內(nèi)存的使用
· 對釋放后內(nèi)存的讀/寫
· 對已分配內(nèi)存塊尾部的讀/寫
· 內(nèi)存泄露
· 不匹配的使用malloc/new/new[] 和 free/delete/delete[]
· 重復(fù)釋放內(nèi)存
猜你喜歡:
c語言入門教程下載