[VC++] Cum gasesc sursa pentru memory leaks?

Mediul de dezvoltare Visual C++, instalare, setari, debugger, compilator, linker si documentatie (forum moderat)
Post Reply
User avatar
Marius Bancila
Fondator
Fondator
Posts: 2344
Joined: 11 Jul 2007, 11:45
Judet: Timiş
Location: Timisoara
Contact:

[VC++] Cum gasesc sursa pentru memory leaks?

Post by Marius Bancila » 12 Jul 2010, 10:50

Intrebare: Programul meu are unele memory leaks. Debuggerul imi afiseaza o lista la sfarsitul executiei:
Detected memory leaks!
Dumping objects ->
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\strcore.cpp(141) : {381} normal block at 0x001FFC30, 54 bytes long.
Data: < x > 0C 00 B9 78 12 00 00 00 12 00 00 00 01 00 00 00
d:\marius\vc++\memoryleakstest\memoryleakstestdlg.cpp(163) : {380} normal block at 0x001FFBF0, 4 bytes long.
Data: <@ > 40 FC 1F 00
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\thrdcore.cpp(306) : {374} client block at 0x001FFA38, subtype c0, 68 bytes long.
a CWinThread object at $001FFA38, 68 bytes long
Object dump complete.
Pe unele dintre ele le gasesc si le pot rezolva, dar nu imi dau seama la toate unde sunt facute alocarile. Cum pot rezolva aceasta problema?

Raspuns: Se poate folosi variabila globala _crtBreakAlloc pentru a forta debuggerul sa se opreasca atunci cand un anumit bloc de memorie este alocat. Pentru aceasta ar trebui urmati cativa pasi:
  1. Trebuie gasit un numar de alocare proproductibil (adica la rulari consecutive sa apara acelasi numar de alocare pentru acelasi memory leak). Memoria se aloca in blocuri si fiecare bloc este identificat printr-un numar numit numar de alocare ("allocation number"). Atunci cand debuggerul printeaza lista de memory leakuri, pentru fiecare bloc include si acest numar de alocare intre acolade, de exemplu {381}.
  2. Pune un brakpoint undeva la inceputul programului. Poate fi in functia main(), in constructorul clasei derivate din CWinApp, in functia InitInstance() sau alte locuri, depinde de tipul proiectului si cat de repede este alocat blocul respectiv. Numere mai mici de alocare indica faptul ca blocul s-a alocat mai repede in executia programului.
  3. Ruleaza programul in debugger.
  4. Cand debuggerul va opri executia (la acel breakpoint de la inceput) deschide fereastra de Watch si adauga in coloana Name urmatorul text: {,,msvcr90d.dll}_crtBreakAlloc. In coloana Value adauga numarul de alocare. Atentie: msvcr90d.dll (DLL-ul pentru C runtime library) este specific pentru Visual Studio 2008. Pentru alte versiuni trebuie folosit DLL-ul corespunzator.
  5. Continua executia programului.
  6. Programul va fi oprit din nou cand se face alocarea blocului respectiv, la urmatoarea linie din dbgheap.c:

    Code: Select all

    /* break into debugger at specific memory allocation */
    if (_crtBreakAlloc != -1L && lRequest == _crtBreakAlloc)
        _CrtDbgBreak();
    
    Deschide fereastra Call Stack si cauta de sus in jos prima functie din codul scris de tine. Vei ajunge la linia care genereaza alocarea de memorie ce nu mai este stearsa.


Marius Bancila
Fondator Codexpert, Microsoft MVP VC++
Site personal | Blog

Post Reply