2016-02-12 2 views
0

У моей программы большие утечки. Я использую отладки кучу, помещая это в мой stdafx.h:показать местоположение самой большой утечки памяти на Windows

#define _CRTDBG_MAP_ALLOC 
#include <stdlib.h> 
#include <crtdbg.h> 

Тогда я захватывая все утечки в текстовый файл, поместив этот код непосредственно перед выходом:

HANDLE hLogFile; 
hLogFile = CreateFile("T:\\MyProject\\heap.txt", GENERIC_WRITE, 
         FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 
         FILE_ATTRIBUTE_NORMAL, NULL); 
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); 
_CrtSetReportFile(_CRT_WARN, hLogFile); 

_CrtDumpMemoryLeaks(); 

exit(EXIT_SUCCESS); 

Однако даже тогда данные утечки утечки, что слишком низкоуровневая информация.

ответ

0

Входя в _CrtDumpMemoryLeaks(), код на самом деле легко следовать. Я написал свою собственную функцию, которая суммирует данные, сообщает байты, пропущенные для каждой строки кода и сортируя по размеру утечки.

Однако для работы требуется статическая переменная внутри dbgheap.c. Я попытался сделать версию dbgheap.c, у которой нет этих статических символов, и попытался сделать из нее мини-DLL (но он жалуется на отсутствующий символ, который я не могу найти нигде в коде MSFT, _heap_regions). Вместо того, что я остановился на помещает этот код прямо перед кодом выше вызова _CrtDumpMemoryLeaks():

// Put a breakpoint here; step INTO the malloc, then in variable watch 
// window evaluate: _CrtDumpMemoryLeakSummary(_pFirstBlock); 
void* pvAccess = malloc(1); 

И в свою очередь это код _CrtDumpMemoryLeakSummary функции:

#define _CRTBLD 
    #include "C:\Program Files\Microsoft Visual Studio 9.0\VC\crt\src\dbgint.h" 

    typedef struct { 
     const char* pszFileName; 
     int   iLine; 
     int   iTotal; 
    } Location_T; 

    #define MAX_SUMMARY 5000 
    static Location_T aloc[ MAX_SUMMARY ]; 



    static int CompareFn(const void* pv1, const void* pv2) { 
     Location_T* ploc1 = (Location_T*) pv1; 
     Location_T* ploc2 = (Location_T*) pv2; 

     if (ploc1->iTotal > ploc2->iTotal) 
      return -1; 
     if (ploc1->iTotal < ploc2->iTotal) 
      return 1; 
     return 0; 
    } 



    void _CrtDumpMemoryLeakSummary(_CrtMemBlockHeader* pHead) 
    { 
      int iLocUsed = 0, iUnbucketed = 0, i; 

      for (/*pHead = _pFirstBlock */; 
       pHead != NULL && /* pHead != _pLastBlock && */ iLocUsed < MAX_SUMMARY; 
       pHead = pHead->pBlockHeaderNext) { 

       const char* pszFileName = pHead->szFileName ? pHead->szFileName : "<UNKNOWN>"; 

       // Linear search is theoretically horribly slow but saves trouble of 
       // avoiding heap use while measuring heap use. 
       int i; 
       for (i = 0; i < iLocUsed; i++) { 

        // To speed search, compare line number (fast) before strcmp() (slow). 
        // If szFileName were guaranteed to be __LINE__ then we could take advantage 
        // of __LINE__ always having the same address for any given file, and just 
        // compare pointers rather than using strcmp(). However, szFileName could 
        // be something else. 

        if (pHead->nLine == aloc[i].iLine && 
         strcmp(pszFileName, aloc[i].pszFileName) == 0) { 
         aloc[i].iTotal += pHead->nDataSize; 
         break; 
        } 
       } 

       if (i == iLocUsed) { 
        aloc[i].pszFileName = pszFileName; 
        aloc[i].iLine  = pHead->nLine; 
        aloc[i].iTotal  = pHead->nDataSize; 
        iLocUsed++; 
       }    
      } 

      if (iLocUsed == MAX_SUMMARY) 
       _RPT0(_CRT_WARN, "\n\n\nARNING: RAN OUT OF BUCKETS! DATA INCOMPLETE!!!\n\n\n"); 

      qsort(aloc, iLocUsed, sizeof(Location_T), CompareFn); 

      _RPT0(_CRT_WARN, "SUMMARY OF LEAKS\n"); 
      _RPT0(_CRT_WARN, "\n"); 
      _RPT0(_CRT_WARN, "bytes leaked code location\n"); 
      _RPT0(_CRT_WARN, "------------ -------------\n"); 

      for (i = 0; i < iLocUsed; i++) 
       _RPT3(_CRT_WARN, "%12d %s:%d\n", aloc[i].iTotal, aloc[i].pszFileName, aloc[i].iLine); 
    } 

Она производит так :

SUMMARY OF LEAKS 

bytes leaked code location 
------------ ------------- 
     912997 <UNKNOWN>:0 
     377800 ..\MyProject\foo.h:205 
     358400 ..\MyProject\A.cpp:959 
     333672 ..\MyProject\B.cpp:359 
     8192 f:\dd\vctools\crt_bld\self_x86\crt\src\_getbuf.c:58 
     6144 ..\MyProject\Interpreter.cpp:196 
     4608 ..\MyProject\Interpreter.cpp:254 
     3634 f:\dd\vctools\crt_bld\self_x86\crt\src\stdenvp.c:126 
     2960 ..\MyProject\C.cpp:947 
     2089 ..\MyProject\D.cpp:1031 
     2048 f:\dd\vctools\crt_bld\self_x86\crt\src\ioinit.c:136 
     2048 f:\dd\vctools\crt_bld\self_x86\crt\src\_file.c:133