原創|行業資訊|編輯:況魚杰|2020-12-03 14:00:47.440|閱讀 502 次
概述:水管泄露了,我們很容易就可以找到那個缺口,可是與水管不一樣,編程軟件中的內存泄漏是很難確定的,因為有大量的數據。在本文中,你可以學習如何在運行時錯誤檢測工具的幫助下,找到C和C++應用程序中的內存泄漏。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
相關鏈接:
	 
 
水管泄露了,我們很容易就可以找到那個缺口,可是與水管不一樣,編程軟件中的內存泄漏是很難確定的,因為有大量的數據。在本文中,你可以學習如何在運行時錯誤檢測工具的幫助下,找到C和C++應用程序中的內存泄漏。
	
當你面臨內存泄漏時,C++和C++有一套運行時檢測工具,或許能夠幫助你提高性能。用C或C++寫代碼的人都會熟悉內存泄漏。維基百科提供了以下定義。
在計算機科學中,內存泄漏是一種資源泄漏,當計算機程序錯誤地管理內存分配時,不再需要的內存沒有被釋放。當一個對象被存儲在內存中,但不能被運行的代碼訪問時,也可能發生內存泄漏。
換句話說,泄漏意味著動態分配的內存不能釋放回操作系統,因為程序不再包含可以訪問它的指針。你已經失去了對那塊內存的控制權,無論大小,都無法再訪問它或釋放它。
運行下面顯示的 "Hello world "程序可以看到這種行為的一個最好的例子。
 /*
 * File: hello.c
 */
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
    char *string, *string_so_far;
    int i, length;     length = 0;
    for(i=0; i<argc; i++) {
        length += strlen(argv[i])+1;
        string = malloc(length+1);
 
        /*  * Copy the string built so far. */
        if(string_so_far != (char *)0)
            strcpy(string, string_so_far);
        else *string = '\0';
        strcat(string, argv[i]);
        if(i < argc-1) strcat(string, " ");
        string_so_far = string;
    }
    printf("You entered: %s\n", string_so_far);
    return (0);
}
如果我們用下面的參數執行這個程序。
hello this is a test如果我們檢查程序在第25行的狀態,就在第二次執行調用malloc之前,我們觀察到:
The variable string_so_far points to the string “hello” which it was assigned as a result of the previous loop iteration. The variable string points to the extended string “hello this” which was assigned on this loop iteration.這些賦值示意圖如下,兩個變量都指向動態分配的內存塊。
下一個說法:
string_so_far = string;將創建指向較長內存塊的兩個變量,如下圖所示:
	
	 
 
然而,一旦發生這種情況,就沒有剩余的指針指向較短的塊了。即使你想這樣做,也無法收回之前被string_so_far指向的內存,它現在已經被永久分配了。這就是所謂的 "內存泄漏"。C++和C++經常會面臨這些常見的問題,所以盡早發現這些問題很重要。
	
雖然沒有 "檢測內存泄漏 "的按鈕,但C++和C有運行時檢測工具可以幫助你。這種類型的錯誤可以通過內存錯誤檢測工具來診斷,比如Parasoft Insure++。如下圖所示。
[hello.c:25] **LEAK_ASSIGN**
>>         string_so_far = string;
  Memory leaked due to pointer reassignment: string
  Lost block : 0x0804bd68 thru 0x0804bd6f (8 bytes)
               string, allocated at hello.c, 15
                          malloc()  (interface)
                            main()  hello.c, 15
  Stack trace where the error occurred:
                            main()  hello.c, 25
這個例子被稱為LEAK_ASSIGN,因為它是在指針被重新分配時引起的。(P.S.其他內存調試器通常不會區分未釋放的內存和實際泄露的內存,但Insure++會區分)。在這種情況下,杰出內存并不是內存的厲害,而是你沒有釋放的內存,與實際泄漏不同的是,實際泄漏是你無法釋放的內存。
	
Parasoft Insure++還可以自動檢測其他幾種類型的泄漏:
| 泄漏類型 | 描述 | 
| LEAK_FREE | 當你釋放一個包含指向其他內存塊的指針的內存塊時發生。 | 
| LEAK_RETURN | 當一個函數返回一個指向分配的內存塊的指針,但返回的值在調用例程中被忽略時發生。 | 
| LEAK_SCOPE | 當一個函數包含一個指向內存塊的局部變量,但函數在返回時沒有將指針保存在全局變量中,也沒有將其傳回給調用者時發生。 | 
請注意,錯誤信息指出了發生問題的確切源行,而不僅僅是分配塊的位置,這是查找和修復內存泄漏的關鍵問題。這一點極為重要,因為很容易將細微的內存泄漏引入到你的應用程序中,但很難將它們全部找到。
如果你正在尋找一個檢查內存泄漏的C++工具,你可以獲得的免費試用。
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@ke049m.cn