內存泄漏問題探討

其實我們大家都聽說過內存泄漏這個概念,但是真正能理解什麼情況能造成內存泄漏、內存泄漏會出現什麼情況、如何避免內存泄漏....

我暫且拋磚引玉,有理解不對的,希望大家指出來。

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)。

 

可以看到內存泄漏了

 

發佈了34 篇原創文章 · 獲贊 4 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章