Linux下C和C 程式中記憶體洩露檢測

2021-10-11 05:11:20 字數 2442 閱讀 5221

c/c++執行高效,不管是作業系統核心還是對性有要求的程式(比如遊戲引擎)都要求使用c/c++來編寫,其實c/c++強大的一點在於能夠使用指標自由地控制記憶體的使用,適時的申請記憶體和釋放記憶體,從而做到其他程式語言做不到的高效地執行。但是記憶體管理是一把雙刃劍,用好了削鐵如泥,用不好自斷一臂。在申請堆上記憶體使用完之後中如果做不到適時有效的釋放,那麼就會造成記憶體洩露,久而久之程式就會將系統記憶體耗盡,導致系統執行出問題。就如同你每天跑去圖書館借一打書籍而不還,直到圖書館倒閉為止。

c語言中申請記憶體和釋放記憶體的方法是使用 malloc和free。

c++中能相容c,所以也能使用malloc和free,物件導向的情況下使用的則是new和delete,能夠自動執行建構函式和析構函式。

在linux平台,我們可以使用valgrind命令檢測c/c++程式是否記憶體洩露。

debian/ubuntu下安裝方法:

deng@itcast:~$ sudo apt install valgrind

deng@itcast:~$ sudo yum install valgrind

安裝好valgrind工具之後,下面來看看valgrind的幾個應用場景。

redhat/centos下安裝方法:

程式中我們定義了乙個指標p,但並未給他分配空間,但我們卻使用它了。

程式示例:

#include #include #include ​int main(void)
valgrind檢測出到我們的程式使用了未初始化的變數。

p所指向的記憶體被釋放了,p變成了野指標,但是我們卻繼續使用這片記憶體。

程式示例:

#include #include #include ​int main(void)    memset(p, 0, sizeof(int));​  *p = 88; ​  printf("*p = %dn", *p);​  //釋放記憶體  free(p);​  printf("*p = %dn", *p);​  return 0;}
valgrind檢測到我們使用了已經free的記憶體,並給出這片記憶體是**分配和**釋放的。

我們動態地分配了一片連續的儲存空間,但我們在訪問個陣列時發生了越界訪問。

程式示例:

#include #include #include ​int main(void)    memset(p, 0, 10 * sizeof(int));​  for (int i = 0; i <= 5; i++)     ​  for (int i = 0; i <= 5; i++)     ​  return 0;}
valgrind檢測出越界資訊如下。

注意:

valgrind不檢查非動態分配陣列的使用情況。

記憶體洩漏的原因在於我們使用free或者new分配空間之後,沒有使用free或者delete釋放記憶體。

程式示例:

#include #include #include ​int main(void)
valgrind的記錄顯示上面的程式用了1次malloc,卻呼叫了0次free。

可以使用--leak-check=full進一步獲取記憶體洩漏的資訊,比如malloc具體行號。

一般我們使用malloc分配的空間,必須使用free釋放記憶體。使用new分配的空間,使用delete釋放記憶體。

程式示例:

#include #include #include ​int main(void)
不匹配地使用malloc/new/new 和 free/delete/delete則會被提示mismacth

一般情況下,記憶體分配一次,只釋放一次。如果多次釋放,可能會出現double free。

程式示例:

#include #include #include ​int main(void)
多次釋放同一記憶體,出現非法釋放記憶體。

記憶體洩露問題非常難定位,對於小工程專案來說,簡單去檢查**中new和delete的匹配對數就基本能定位到問題,但是一旦**量上公升到以萬單位時,僅靠肉眼檢查來定位問題那就非常困難了,所以我們需要利用工具幫助我們找出問題所在。在linux系統下記憶體檢測工具首推valgrind,一款非常好用的開源記憶體管理工具。valgrind其實是乙個工具集,記憶體錯誤檢測只是它眾多功能的乙個,但我們用得最多的功能正是它——memcheck。

總之,valgrind工具可以檢測下列與記憶體相關的問題 :

· 未釋放記憶體的使用

· 對釋放後記憶體的讀/寫

· 對已分配記憶體塊尾部的讀/寫

· 記憶體洩露

· 不匹配的使用malloc/new/new 和 free/delete/delete

· 重複釋放記憶體

linux 下 C 程式 程序 記憶體布局

記憶體對映段 堆的起始位址加上隨機的偏移量來打亂布局。不幸的是,32 位位址空間相當緊湊,給隨機化所留下的空當不大,削弱了這種技巧的效果 程序位址空間中最頂部的段是棧,大多數程式語言將之用於儲存區域性變數和函式引數。呼叫乙個方法或函式會將乙個新的棧楨 stack frame 壓入棧中。棧楨在函式返回...

C 反射呼叫WebService引起記憶體洩漏

最近寫了乙個小工具,用來定時檢測公司各台伺服器上的webservice是否工作正常.如果無法訪問則報警.開發思路也很簡單,設定乙個timer,定時啟動多個執行緒 每個執行緒負責n臺伺服器訪問任務 去動態訪問各伺服器上的webservice的指定方法.然後對異常資訊進行報警.動態訪問webservic...

ArcEngine開發程式中關閉時記憶體洩漏的問題

arcengine開發程式中關閉時記憶體洩漏的問題 一 ae9.0和9.1中解決辦法 在ae9.0和9.1中,就出現了arcengine開發程式中關閉時記憶體洩漏的問題,彈出個錯誤,讓人十分不爽.後來查詢相關資料,需要在關閉窗體時,加乙個函式。void frmmain closing object ...