日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

【Tools】Linux下C和C++程序中内存泄露检测

發布時間:2024/4/24 linux 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Tools】Linux下C和C++程序中内存泄露检测 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

00. 目錄

文章目錄

    • 00. 目錄
    • 01. 前言
    • 02. valgrind安裝
    • 03. 使用未初始化的內存
    • 04. 使用野指針
    • 05. 動態內存越界訪問
    • 06. 分配空間后沒有釋放
    • 07. 不匹配使用delete或者free
    • 08. 兩次釋放同一塊內存
    • 09. 總結
    • 10. 附錄

01. 前言

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

C語言中申請內存和釋放內存的方法是使用 malloc和free。

C++中能兼容C,所以也能使用malloc和free,面向對象的情況下使用的則是new和delete,能夠自動執行構造函數和析構函數。

在Linux平臺,我們可以使用valgrind命令檢測C/C++程序是否內存泄露。

02. valgrind安裝

debian/ubuntu下安裝方法:

deng@itcast:~$ sudo apt install valgrind

redhat/centos下安裝方法:

deng@itcast:~$ sudo yum install valgrind

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

03. 使用未初始化的內存

程序中我們定義了一個指針p,但并未給他分配空間,但我們卻使用它了。

程序示例:

#include <stdio.h> #include <string.h> #include <stdlib.h> int main(void) {char ch; char *p; ch = *p; printf("ch = %c\n", ch);return 0; }

valgrind檢測出到我們的程序使用了未初始化的變量。

04. 使用野指針

p所指向的內存被釋放了,p變成了野指針,但是我們卻繼續使用這片內存。

程序示例:

#include <stdio.h> #include <string.h> #include <stdlib.h> int main(void) {int *p = NULL;p = malloc(sizeof(int));if (NULL == p){ printf("malloc failed...\n"); return 1;} memset(p, 0, sizeof(int));*p = 88; printf("*p = %d\n", *p);//釋放內存free(p);printf("*p = %d\n", *p);return 0; }

valgrind檢測到我們使用了已經free的內存,并給出這片內存是哪里分配和哪里釋放的。

05. 動態內存越界訪問

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

程序示例:

#include <stdio.h> #include <string.h> #include <stdlib.h> int main(void) {int i = 0;int *p = NULL;p = malloc(5 * sizeof(int));if (NULL == p){ printf("malloc failed...\n"); return 1;} memset(p, 0, 10 * sizeof(int));for (int i = 0; i <= 5; i++) { p[i] = i + 1; } for (int i = 0; i <= 5; i++) { printf("p[%d]: %d\n", i, p[i]);} return 0; }

valgrind檢測出越界信息如下。

注意:

valgrind不檢查非動態分配數組的使用情況。

06. 分配空間后沒有釋放

內存泄漏的原因在于我們使用free或者new分配空間之后,沒有使用free或者delete釋放內存。

程序示例:

#include <stdio.h> #include <string.h> #include <stdlib.h> int main(void) {int *p = NULL;p = malloc(sizeof(int));*p = 88; printf("*p = %d\n", *p);return 0; }

valgrind的記錄顯示上面的程序用了1次malloc,卻調用了0次free。

可以使用–leak-check=full進一步獲取內存泄漏的信息,比如malloc具體行號。

07. 不匹配使用delete或者free

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

程序示例:

#include <stdio.h> #include <string.h> #include <stdlib.h> int main(void) {int *p = NULL;p = (int *)malloc(sizeof(int));*p = 88; printf("*p = %d\n", *p);delete p;return 0; }

不匹配地使用malloc/new/new[] 和 free/delete/delete[]則會被提示mismacth

08. 兩次釋放同一塊內存

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

程序示例:

#include <stdio.h> #include <string.h> #include <stdlib.h> int main(void) {int *p = NULL;p = (int *)malloc(sizeof(int));*p = 88; printf("*p = %d\n", *p);free p;free p;return 0; }

多次釋放同一內存,出現非法釋放內存。

09. 總結

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

總之,valgrind工具可以檢測下列與內存相關的問題 :

  • 未釋放內存的使用
  • 對釋放后內存的讀/寫
  • 對已分配內存塊尾部的讀/寫
  • 內存泄露
  • 不匹配的使用malloc/new/new[] 和 free/delete/delete[]
  • 重復釋放內存

10. 附錄

總結

以上是生活随笔為你收集整理的【Tools】Linux下C和C++程序中内存泄露检测的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。