其实我们大家都听说过内存泄漏这个概念,但是真正能理解什么情况能造成内存泄漏、内存泄漏会出现什么情况、如何避免内存泄漏....
我暂且抛砖引玉,有理解不对的,希望大家指出来。
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)。
可以看到内存泄漏了