原創(chuàng)|行業(yè)資訊|編輯:況魚杰|2020-12-03 14:00:47.440|閱讀 488 次
概述:水管泄露了,我們很容易就可以找到那個(gè)缺口,可是與水管不一樣,編程軟件中的內(nèi)存泄漏是很難確定的,因?yàn)橛写?量的數(shù)據(jù)。在本文中,你可以學(xué)習(xí)如何在運(yùn)行時(shí)錯(cuò)誤檢測工具的幫助下,找到C和C++應(yīng)用程序中的內(nèi)存泄漏。
# 界面/圖表報(bào)表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
相關(guān)鏈接:
水管泄露了,我們很容易就可以找到那個(gè)缺口,可是與水管不一樣,編程軟件中的內(nèi)存泄漏是很難確定的,因?yàn)橛写罅康臄?shù)據(jù)。在本文中,你可以學(xué)習(xí)如何在運(yùn)行時(shí)錯(cuò)誤檢測工具的幫助下,找到C和C++應(yīng)用程序中的內(nèi)存泄漏。
當(dāng)你面臨內(nèi)存泄漏時(shí),C++和C++有一套運(yùn)行時(shí)檢測工具,或許能夠幫助你提高性能。用C或C++寫代碼的人都會(huì)熟悉內(nèi)存泄漏。維基百科提供了以下定義。
在計(jì)算機(jī)科學(xué)中,內(nèi)存泄漏是一種資源泄漏,當(dāng)計(jì)算機(jī)程序錯(cuò)誤地管理內(nèi)存分配時(shí),不再需要的內(nèi)存沒有被釋放。當(dāng)一個(gè)對象被存儲(chǔ)在內(nèi)存中,但不能被運(yùn)行的代碼訪問時(shí),也可能發(fā)生內(nèi)存泄漏。
換句話說,泄漏意味著動(dòng)態(tài)分配的內(nèi)存不能釋放回操作系統(tǒng),因?yàn)槌绦虿辉侔梢栽L問它的指針。你已經(jīng)失去了對那塊內(nèi)存的控制權(quán),無論大小,都無法再訪問它或釋放它。
運(yùn)行下面顯示的 "Hello world "程序可以看到這種行為的一個(gè)最好的例子。
/* * 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); }如果我們用下面的參數(shù)執(zhí)行這個(gè)程序。
hello this is a test如果我們檢查程序在第25行的狀態(tài),就在第二次執(zhí)行調(diào)用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.這些賦值示意圖如下,兩個(gè)變量都指向動(dòng)態(tài)分配的內(nèi)存塊。
下一個(gè)說法:
string_so_far = string;將創(chuàng)建指向較長內(nèi)存塊的兩個(gè)變量,如下圖所示:
然而,一旦發(fā)生這種情況,就沒有剩余的指針指向較短的塊了。即使你想這樣做,也無法收回之前被string_so_far指向的內(nèi)存,它現(xiàn)在已經(jīng)被永久分配了。這就是所謂的 "內(nèi)存泄漏"。C++和C++經(jīng)常會(huì)面臨這些常見的問題,所以盡早發(fā)現(xiàn)這些問題很重要。
雖然沒有 "檢測內(nèi)存泄漏 "的按鈕,但C++和C有運(yùn)行時(shí)檢測工具可以幫助你。這種類型的錯(cuò)誤可以通過內(nèi)存錯(cuò)誤檢測工具來診斷,比如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這個(gè)例子被稱為LEAK_ASSIGN,因?yàn)樗窃谥羔槺恢匦路峙鋾r(shí)引起的。(P.S.其他內(nèi)存調(diào)試器通常不會(huì)區(qū)分未釋放的內(nèi)存和實(shí)際泄露的內(nèi)存,但I(xiàn)nsure++會(huì)區(qū)分)。在這種情況下,杰出內(nèi)存并不是內(nèi)存的厲害,而是你沒有釋放的內(nèi)存,與實(shí)際泄漏不同的是,實(shí)際泄漏是你無法釋放的內(nèi)存。
Parasoft Insure++還可以自動(dòng)檢測其他幾種類型的泄漏:
泄漏類型 |
描述 |
LEAK_FREE |
當(dāng)你釋放一個(gè)包含指向其他內(nèi)存塊的指針的內(nèi)存塊時(shí)發(fā)生。 |
LEAK_RETURN |
當(dāng)一個(gè)函數(shù)返回一個(gè)指向分配的內(nèi)存塊的指針,但返回的值在調(diào)用例程中被忽略時(shí)發(fā)生。 |
LEAK_SCOPE |
當(dāng)一個(gè)函數(shù)包含一個(gè)指向內(nèi)存塊的局部變量,但函數(shù)在返回時(shí)沒有將指針保存在全局變量中,也沒有將其傳回給調(diào)用者時(shí)發(fā)生。 |
請注意,錯(cuò)誤信息指出了發(fā)生問題的確切源行,而不僅僅是分配塊的位置,這是查找和修復(fù)內(nèi)存泄漏的關(guān)鍵問題。這一點(diǎn)極為重要,因?yàn)楹苋菀讓⒓?xì)微的內(nèi)存泄漏引入到你的應(yīng)用程序中,但很難將它們?nèi)空业健?
如果你正在尋找一個(gè)檢查內(nèi)存泄漏的C++工具,你可以獲得的免費(fèi)試用。
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請郵件反饋至chenjj@fc6vip.cn