1. 程式人生 > >Linux平臺下如何檢測、除錯C/C++程式記憶體洩漏

Linux平臺下如何檢測、除錯C/C++程式記憶體洩漏

1."記憶體洩露"包括堆記憶體洩露、棧記憶體洩露。根據記憶體的型別,又分為:記憶體申請、釋放,控制代碼的開啟與關閉問題。
2.容易忽視的是棧上的記憶體洩露,嚴格來講是申請的記憶體超過執行緒棧空間大小(預設為1MB)。棧上的記憶體(即區域性變數)是不需要釋放的,函式返回自動出棧(釋放)。若某時刻超過執行緒棧空間大小,造成其它使用棧的地方不能正常工作(如函式呼叫、SEH等),會使程式崩潰(驅動的話會藍屏)。所以申請區域性變數記憶體時,不要太大。
3.堆記憶體申請、釋放。主要是要注意申請的地方要記得釋放,以及申請、釋放函式要配對使用。比如malloc和free、new和delete、BSTR的SysAllocString和SysFreeString。
4.還有一個地方也往往被忽略,"控制代碼的開啟與關閉

問題"。這個當積累到一定數量,是很佔記憶體的。可以linux上的加強程序檢視工具觀察,若handle數量很大或一直在增長,說明有洩漏。windows下則可以使用微軟核心套件SysinternalsSuite出品的procexp.exe工具,如下圖:
請輸入圖片描述

看到handles欄了嗎。

另外,完全可以過載new、delete等方法,實現簡單的垃圾回收,很多軟體都這麼做。這也是<<Effective C++>>上推薦的。

檢測記憶體洩漏的主要工具是偵錯程式和 C 執行庫 (CRT) 除錯堆函式。

若要啟用除錯堆函式,請在程式中包括以下語句:

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
說明

#include 語句必須採用上文所示順序。 如果更改了順序,所使用的函式可能無法正常工作。

通過包括 crtdbg.h,將 malloc 和 free 函式對映到它們的除錯版本,即 _malloc_dbg 和 _free_dbg,這兩個函式將跟蹤記憶體分配和釋放。 此對映只在除錯版本(在其中定義了 _DEBUG)中發生。釋出版本使用普通的 malloc 和 free 函式。

#define 語句將 CRT 堆函式的基版本對映到對應的“Debug”版本。 並非絕對需要該語句;但如果沒有該語句,記憶體洩漏轉儲包含的有用資訊將較少。

在添加了上述語句之後,可以通過在程式中包括以下語句(通常應恰好放在程式退出位置之前)來轉儲記憶體洩漏資訊:

_CrtDumpMemoryLeaks();
當在偵錯程式下執行程式時,_CrtDumpMemoryLeaks 將在“輸出”視窗中顯示記憶體洩漏資訊。 記憶體洩漏資訊如下所示:

Detected memory leaks!Dumping objects -> C:\PROGRAM FILES\VISUAL STUDIO\MyProjects\leaktest\leaktest.cpp(20) : {18} normal block at 0x00780E80, 64 bytes long.Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD Object dump complete.

如果沒有使用 #define _CRTDBG_MAP_ALLOC 語句,記憶體洩漏轉儲將如下所示:

Detected memory leaks!Dumping objects -> {18} normal block at 0x00780E80, 64 bytes long.Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD Object dump complete.
未定義 _CRTDBG_MAP_ALLOC 時,所顯示的會是:

記憶體分配編號(在大括號內)。

塊型別(普通、客戶端或 CRT)。

十六進位制形式的記憶體位置。

以位元組為單位的塊大小。

前 16 位元組的內容(亦為十六進位制)。

定義了 _CRTDBG_MAP_ALLOC 時,還會顯示在其中分配洩漏的記憶體的檔案。 檔名後括號中的數字(本示例中為 20)是該檔案中的行號。

轉到原始檔中分配記憶體的行

在“輸出”視窗中雙擊包含檔名和行號的行。

  • 或 -

在“輸出”視窗中選擇包含檔名和行號的行,然後按 F4。

_CrtSetDbgFlag

如果程式總是在同一位置退出,呼叫 _CrtDumpMemoryLeaks 將非常容易。 如果程式從多個位置退出,則無需在每個可能退出的位置放置對 _CrtDumpMemoryLeaks 的呼叫,而可以在程式開始處包含以下呼叫:

複製

_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
該語句在程式退出時自動呼叫 _CrtDumpMemoryLeaks。 必須同時設定 _CRTDBG_ALLOC_MEM_DF 和 _CRTDBG_LEAK_CHECK_DF 兩個位域,如前面所示。

設定 CRT 報告模式

預設情況下,_CrtDumpMemoryLeaks 將記憶體洩漏資訊轉儲到“輸出”視窗的“除錯”窗格,如上所述。 可以使用 _CrtSetReportMode 重置該設定,以轉儲到另一位置。

如果使用庫,它可以將輸出重置到另一位置。


相關推薦

C/C++應用程式記憶體洩漏檢查統計方案

  一、前緒   C/C++程式給某些程式設計師的幾大印象之一就是記憶體自己管理容易洩漏容易崩,筆者曾經在一個產品中使用C語言開發維護部分模組,只要產品有記憶體洩漏和崩潰的問題,就被甩鍋“我的程式是C#開發的記憶體都是託管的,C++那邊也沒有記憶體(庇護其好友),肯定是C這邊的問題”

Linux平臺如何檢測除錯C/C++程式記憶體洩漏

1."記憶體洩露"包括堆記憶體洩露、棧記憶體洩露。根據記憶體的型別,又分為:記憶體申請、釋放,控制代碼的開啟與關閉問題。 2.容易忽視的是棧上的記憶體洩露,嚴格來講是申請的記憶體超過執行緒棧空間大小(預設為1MB)。棧上的記憶體(即區域性變數)是不需要釋放的,函式返回自動出棧(釋放)。若某時刻超過執行緒棧

Windows開發除錯Linux C/C++程式

背景 據我所知,開發Linux C/C++ 程式的一般方式,如下: ² 使用SecureCRT+UltraEdit(FTP)工具遠端編輯、編譯(Makefile+gcc)、除錯(gdb)Linux程式。 ² Windows 上裝Linux虛擬機器,在虛擬機器上使用Vim、g

Linux平臺基於BitTorrent應用層協議的下載軟體開發--Main函式模組(main.c

#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <malloc.h> #include

Linux環境使用GDB除錯C程式

寫這篇部落格的目的是因為我剛剛用gdb解決了一個c語言中賦錯了值的問題,導致整個程式的執行結果是不正常的,這是我求助於gdb解決了這個問題,之前也用gdb這個神器解決過一些執行時的記憶體問題,比如說c程式中非常常見的segment error。這篇部落格為了對g

linuxHttpGetHttpPost的C++實現

#include "HttpRequest.h" int main() { HttpRequest* Http = new HttpRequest; char* str = (char*)malloc(BUFSIZE); memset(str, 0, B

linux平臺基於C語言實現遍歷檔案目錄

#include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <string.h&g

java零碎要點012---linux Centos編譯執行除錯java程式

   JAVA技術交流QQ群:170933152  有時候要除錯一些東西,適不適用Linux,還是需要在Linux上弄啊 Linux上步驟: 安裝jdk 安裝以後vi Test.java 然後編寫程式: import java.io.File;

Linux環境如何編譯和執行c程式

1 單個檔案的編譯和執行 建立main.c檔案,內容如下:  編譯: 執行: 2 多個檔案的編譯和執行建立sum.c檔案,內容如下: 建立main.c檔案,內容如下:   編譯:    生成可執行檔案,檔名為main: 執行程式:

Linux環境如何編譯和執行c程序

文件的 ron 當前 cto directory 變量 沒有 執行文件 nbsp 1 單個文件的編譯和執行 創建main.c文件,內容如下: 編譯: 執行: 2 多個文件的編譯和執行創建sum.c文件,內容如下: 創建main.c文件,內容如下: 編譯:

UnixC程式記憶體洩漏檢測工具Valgrind安裝與使用

                Valgrind是一款用於記憶體除錯、記憶體洩漏檢測以及效能分析的軟體開發工具。 Valgrind的最初作者是Julian Seward,他於2006年由於在開發Valgrind上的工作獲得了第二屆Google-O'Reilly開原始碼獎。 Valgrind遵守GNU通用公共許

Linux CentOS安裝配置mysql數據庫

config 得到 操作 program except naconda 服務端 強力 fig 假設要在Linux上做j2ee開發。首先得搭建好j2ee的開發環境。包含了jdk、tomcat、eclipse的安裝(這個在之前的一篇隨筆中已經有具體解說了Linux學習之Ce

linux平臺防火墻iptables原理(轉)

arch inux 方式 輸出結果 取反 地址 angle 啟動 internet iptables簡介 netfilter/iptables(簡稱為iptables)組成Linux平臺下的包過濾防火墻,與大多數的Linux軟件一樣,這個包過濾防火墻是免費的,它可以

Golang 入門基礎教程(二)Linux 平臺安裝Golang基礎環境

Linux平臺下安裝Golang的話可以直接下載官方原始碼包, 注意:如果系統內安裝過其他版本的Golang原始碼包,必須先將之前的清除掉 1、解壓原始碼包 解壓原始碼包到 /usr/local目錄下 > sudo tar -C /usr/local

Linux平臺下載百度網盤裡的資源

工作中大部分使用的是Linux系統,經常會遇到需要下載資源的情況,這時候就懵逼了,Linux下根本沒有百度網盤客戶端啊,雖然可以隨時切換到windows環境下,繼續下載,但是終歸不是好辦法。所以今天就特意找了下相關方法,一搜還真多,七七八八的都不知道選哪個好。看上去都是比較複雜又要搞原始碼又要搞配置

Linux 平臺的漏洞掃描器 Vuls

Vuls 是一款適用於 Linux/FreeBSD 的漏洞掃描程式,無代理,採用 Go 語言編寫,對於系統管理員來說,每天必須執行安全漏洞分析和軟體更新都是一個負擔。 為避免生產環境宕機,系統管理員通常選擇不使用軟體包管理器提供的自動更新選項,而是手動執行

Linux平臺安裝MongoDB(3.0.6)

          MongoDB資料庫在Linux平臺下的安裝也是比較簡單的,直接解壓,然後啟動MongoDB服務就可以了,具體的安裝步驟如下: 1.下載MongoDB資料庫 由於我自己的Linux

盤點Linux平臺的高可用叢集軟體(High Availability Cluster- HA)

由於X86硬體平臺伺服器的成本下降及其穩定性的提高,越來越多的廠家在小型機之外多了個選擇,因此基於X86平臺的Linux系統在企業級應用中普及起來,這篇文章將要介紹的是基於Linux的叢集軟體,它們主要分成三大類( 高可用叢集, 負載均衡叢集,科學計算叢集): 高可用叢集( High Availab

基於Linux平臺的僵屍網路病毒《比爾蓋茨》

感覺分析的很好,所以決定翻譯出來,希望和大家多多交流O(∩_∩)O~ 轉載請註明出處:http://blog.csdn.net/u010484477     O(∩_∩)O謝謝 關鍵字:病毒,linux,資訊保安 我昨天寫的日誌裡面提到,家用路由器在x86的

Linux平臺啟動和關閉MySQL服務

首先需要檢視下載MySQL服務的狀態 [[email protected] bin]# netstat -nlp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Addr