在寫大型C/C++工程時不免會發生內存泄漏現象,系統編程中一個重要的方面就是有效地處理與內存相關的問題。你的工做越接近系統,你就須要面對越多的內存問題。有時這些問題很是瑣碎,而更多時候它會演變成一個調試內存問題的惡夢。 常見的內存問題一共七種:1. 動態內存泄露;2. 資源泄露,好比文件指針不關閉;3. 動態內存越界;4.數組內存越界;5.動態內存double free;6.使用野指針,即未初始化的指針;7.釋放野指針,即未初始化的指針。 內存問題很是難定位,對於小工程來講,簡單去檢查代碼中new和delete的匹配對數就基本能定位到問題,可是一旦代碼量上升到以萬單位時,僅靠肉眼檢查來定位問題那就很是困難了,因此咱們須要利用工具幫助咱們找出問題所在。在Linux系統下內存檢測工具首推Valgrind,一款很是好用的開源內存管理框架。Valgrind實際上是一個工具集,內存錯誤檢測只是它衆多功能的一個,但咱們用得最多的功能正是它——memcheck。 該工具能夠檢測下列與內存相關的問題 : 未釋放內存的使用 對釋放後內存的讀/寫 對已分配內存塊尾部的讀/寫 內存泄露 不匹配的使用malloc/new/new[] 和 free/delete/delete[] 重複釋放內存 首先安裝Valgrind很是簡單: //valgrind下載:http://valgrind.org/downloads/valgrind-3.12.0.tar.bz2valgrind安裝:1. tar -jxvf valgrind-3.12.0.tar.bz22. cd valgrind-3.12.03. ./configure4. make5. sudo make install 下面開始講解Valgrind的應用場景。 注意: 下面討論的全部測試代碼都應該使用gcc/g++而且加上-g選項。 1. 使用未初始化的內存(使用野指針) 這裏咱們定義了一個指針p,但並未給他開闢空間,即他是一個野指針,但咱們卻使用它了。 Valgrind檢測出咱們程序使用了未初始化的變量,但並未檢測出內存泄漏。 2.在內存被釋放後進行讀/寫(使用野指針) p所指向的內存被釋放了,p變成了野指針,可是咱們卻繼續使用這片內存。 Valgrind檢測出咱們使用了已經free掉的內存,並給出這片內存是哪裏分配哪裏釋放的。 3.從已分配內存塊的尾部進行讀/寫(動態內存越界) 咱們動態地分配了一段數組,但咱們在訪問個數組時發生了越界讀寫,程序crash掉。 Valgrind檢測出越界的位置。 注意:Valgrind不檢查靜態分配數組的使用狀況!因此對靜態分配的數組,Valgrind表示無能爲力!好比下面的例子,程序crash掉,咱們殊不知道爲何。 4.內存泄漏 內存泄漏的緣由在於沒有成對地使用malloc/free和new/delete,好比下面的例子。 Valgrind會給出程序中malloc和free的出現次數以判斷是否發生內存泄漏,好比對上面的程序運行memcheck,Valgrind的記錄顯示上面的程序用了1次malloc,卻調用了0次free,明顯發生了內存泄漏! 上面提示了咱們可使用--leak-check=full進一步獲取內存泄漏的信息,好比malloc和free的具體行號。 5. 不匹配地使用malloc/new/new[] 和 free/delete/delete[] 正常使用new/delete和malloc/free是這樣子的: 而不匹配地使用malloc/new/new[] 和 free/delete/delete[]則會被提示mismacth: 6.兩次釋放內存 double free的狀況一樣是根據malloc/free的匹配對數來體現的,好比free多了一次,Valgrind也會提示。 固然,Valgrind也不是萬能的。Valgrind也有沒法找到問題的時候,有些問題只能經過不斷的review代碼找到了癥結。發現問題,解決問題,畢竟是末流。最好的方法,就是不引入內存問題。這能夠經過良好的代碼風格和設計來實現的。 文末也給你們,分享主要有C/C++,Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒體,CDN,P2P,K8S,Docker,TCP/IP,協程,DPDK技術,面試技巧方面的資料技術討論。 感興趣的朋友能夠加羣:812855908