其實我們大家都聽說過內存泄漏這個概念,但是真正能理解什麼情況能造成內存泄漏、內存泄漏會出現什麼情況、如何避免內存泄漏....
我暫且拋磚引玉,有理解不對的,希望大家指出來。
1、在C語言中,當你 malloc一塊新的內存後沒有回收、創建的文件句柄沒有關閉、創建的Socket描述符沒有關閉....都會造成內存泄漏,所以一般情況下,在堆中開闢的內存不用後free掉,不用的文件句柄、Socket描述符Close掉,這樣你的代碼就很安全,也不會造成內存泄漏。
2、在C++ 語言中,與C語言中的一樣上面的那些也會造成內存泄漏,上面的解決方案也可以解決掉內存泄漏。可是我們在C++中習慣用析構函數來釋放資源,也就是說把一些free創建的內存、Close文件句柄操作放在析構函數中,如果在調用完後能正確的delete一個對象(當然對應的是new一個對象時的情況),或者棧能正常退出(對應的是在棧中創建對象,例如 WriteFile wf()),這樣也能保證資源能完全釋放。但是如果你調用在delete之前(或者說調用析構函數之前)調用了exit退出程序,那我負責地告訴你第一程序棧中的資源沒有完全釋放;第二在堆中創建的對象沒有釋放(假如你是把釋放資源放在析構函數中的話)。因爲調用exit是不執行對象的析構函數的。
下面舉個例子:
Head.h文件
#include<iostream>
using namespace std;
class Head
{
public:
Head()
{
printf("執行構造函數/n");
}
void Init()
{
_name=new char[100];
}
~Head()
{
delete [] _name;
printf("執行析構函數/n");
}
private:
char * _name;
};
test.cpp文件
#if defined(_DEBUG)
#include <vld.h>
#endif
#include<stdlib.h>
#include "Head.h"
void End()
{
//h->~Head();
//delete h;
printf("執行End函數..../n");
}
void f(Head * h)
{
/*int *p = new int(0x12345678);
printf("p=%08x, ", p);*/
h->Init();
//delete h;
exit(1);
}
void main()
{
Head * h= new Head();
//atexit(End);
f(h);
}
測試的結果:
Visual Leak Detector Version 1.0 installed (multithreaded DLL).
WARNING: Visual Leak Detector detected memory leaks!
---------- Block 61 at 0x00382BA0: 100 bytes ----------
Call Stack:
0x00411FEA (File and line number not available): (Function name unavailable)
f:/dd/vctools/crt_bld/self_x86/crt/src/dbgmalloc.c (56): malloc
0x00414EFE (File and line number not available): (Function name unavailable)
0x004116FA (File and line number not available): (Function name unavailable)
0x00411696 (File and line number not available): (Function name unavailable)
0x004117DF (File and line number not available): (Function name unavailable)
0x004154A8 (File and line number not available): (Function name unavailable)
0x004152EF (File and line number not available): (Function name unavailable)
0x7C82F23B (File and line number not available): ProcessIdToSessionId
Data:
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD ........ ........
---------- Block 59 at 0x00388C70: 4 bytes ----------
Call Stack:
0x00411FEA (File and line number not available): (Function name unavailable)
f:/dd/vctools/crt_bld/self_x86/crt/src/dbgmalloc.c (56): malloc
0x00411784 (File and line number not available): (Function name unavailable)
0x004154A8 (File and line number not available): (Function name unavailable)
0x004152EF (File and line number not available): (Function name unavailable)
0x7C82F23B (File and line number not available): ProcessIdToSessionId
Data:
A0 2B 38 00 .+8..... ........
Visual Leak Detector detected 2 memory leaks.
“內存泄漏檢測工具.exe”: 已卸載“C:/WINDOWS/system32/dbghelp.dll”
“內存泄漏檢測工具.exe”: 已卸載“C:/WINDOWS/system32/version.dll”
Visual Leak Detector is now exiting.
線程 'Win32 線程' (0x1f6c) 已退出,返回值爲 1 (0x1)。
程序“[7628] 內存泄漏檢測工具.exe: 本機”已退出,返回值爲 1 (0x1)。
可以看到內存泄漏了