Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Обнаружение Утечки Памяти

19K
26 ноября 2007 года
Rost
45 / / 05.07.2007
Всем привет :)
Перейду сразу к делу.. Писал свой очередной проектик, столкнулся с проблемой утечки памяти. Начав поиски по отлавливанию подобного явления быстро наткнулся на статью "Как обнаружить утечку памяти"


После прочтения, приступил к реализации:

Код:
#ifndef _DEBUG_NEW_H_
#define _DEBUG_NEW_H_
 
#include <list>
 
using namespace std;
 
typedef struct tagALLOC_ADDR_INFO
{
 void *   pAddress;
 unsigned long nSize;
 char   szFileName[64];
 unsigned long nFileLine;
}
ALLOC_ADDR_INFO, *PALLOC_ADDR_INFO;
 
static list<ALLOC_ADDR_INFO> AllocList;
 
//-------------------------------------------------------------------------
void   AddressInfo_Add  (void *_pAddr, unsigned long _nSize, const char *_szName, unsigned long _nLine);
void   AddressInfo_Del  (void *_pAddr);
void   AddressInfo_Dump ();
 
void * __cdecl operator new  (size_t _Size, const char *_szFile, unsigned long _nLine);
void * __cdecl operator new[]  (size_t _Size, const char *_szFile, unsigned long _nLine);
void __cdecl operator delete  (void *_pPtr);
void __cdecl operator delete[] (void *_pPtr);
 
#define DEBUG_NEW new(__FILE__, __LINE__)
#define new DEBUG_NEW
//-------------------------------------------------------------------------
#endif

Код:
#include "Debug.h"
#include <windows.h>
//-------------------------------------------------------------------------
void AddressInfo_Add(void *_pAddr, unsigned long _nSize,  const char *_szName, unsigned long _nLine)
{
 ALLOC_ADDR_INFO info;
 
 info.pAddress = _pAddr;
 info.nSize  = _nSize;
 info.nFileLine = _nLine;
 
 strncpy_s(info.szFileName, 63, _szName, 63);
 
 AllocList.insert(AllocList.begin(), info);
};
//-------------------------------------------------------------------------
void AddressInfo_Del(void *_pAddr)
{
 list<ALLOC_ADDR_INFO>::iterator it;
 
 for(it = AllocList.begin(); it != AllocList.end(); it++)
 {
  if(it->pAddress == _pAddr)
  {
   AllocList.erase(it);
   break;
  }
 }
};
//-------------------------------------------------------------------------
void AddressInfo_Dump()
{
 list<ALLOC_ADDR_INFO>::iterator it;
 unsigned long     nTotalSize = 0;
 char       szBuf[1024];
 
 sprintf_s(szBuf, sizeof(szBuf), "[BEGIN]-------------------------------------------");
 OutputDebugStringA(szBuf);
 
 for(it = AllocList.begin(); it != AllocList.end(); it++)
 {
  sprintf_s(szBuf, sizeof(szBuf), "%s:\tLINE %d,tADDRESS %.4X [%d] Unfreed!",
          it->szFileName, it->nFileLine, (unsigned long)it->pAddress, it->nSize);
 
  nTotalSize += it->nSize;
 
  OutputDebugStringA(szBuf);
 }
 
 sprintf_s(szBuf, sizeof(szBuf), "--------------------------------------------------");
 OutputDebugStringA(szBuf);
 
 sprintf_s(szBuf, sizeof(szBuf), "Total Unfreed: %d bytes", nTotalSize);
 OutputDebugStringA(szBuf);
};
//-------------------------------------------------------------------------
void * __cdecl operator new(size_t _Size, const char *_szFile, unsigned long _nLine)
{
 void *pPtr;
 
 if((pPtr = malloc(_Size)) != NULL)
 {
  AddressInfo_Add(pPtr, _Size, _szFile, _nLine);
 }
 else
 {
  throw std::bad_alloc();
 }
 
 return pPtr;
};
//-------------------------------------------------------------------------
void * __cdecl operator new[](size_t _Size, const char *_szFile, unsigned long _nLine)
{
 void *pPtr;
 
 if((pPtr = malloc(_Size)) != NULL)
 {
  AddressInfo_Add(pPtr, _Size, _szFile, _nLine);
 }
 else
 {
  throw std::bad_alloc();
 }
 
 return pPtr;
};
//-------------------------------------------------------------------------
void __cdecl operator delete(void *_pPtr)
{
 AddressInfo_Del(_pPtr);
 free(_pPtr);
};
//-------------------------------------------------------------------------
void __cdecl operator delete[](void *_pPtr)
{
 AddressInfo_Del(_pPtr);
 free(_pPtr);
};
//-------------------------------------------------------------------------

Собственно никаких существенных отличий от кода приведенного в статье нет (хотя в статье допущенны очевидные ошибки, автор сам наверно не пробовал даже это реализовать :). Но вот оператор new перегружается как то коряво и соответсвенно не работоспособно. Просматривал сорцы CRT (new.h), но в этой каше define'ов ничего не понятно.. Прошу помочь с решением данной проблемы.. все таки вещь очень полезная.. если конечно реализуемая, т.к. не понятно как вызывать конструктор деструктор для объектов.. хотя вроде для каждого класса нужно свои операторы new/delete перегружать... тогда получается нельзя создать "глобально перегруженный"?! :)
255
27 ноября 2007 года
Dart Bobr
1.4K / / 09.04.2004
Если ты пишешь под Visual Studio, то там есть стандартные средства ловли memory leak'ов. Только если я не ошибаюсь - они доступны в тим едишн. И код для этого модифицировать не нада. Не знаю, или в более ранних версиях была эта фича или нет, но в 2005 студии, точно есть. Code Analysis называется.
19K
27 ноября 2007 года
Rost
45 / / 05.07.2007
Да пишу конечно под студией (уже под 2008 Team Suite), баги то свои я закрыл дело не в них. Просто интересно было саму идею реализовать.. Да и малоли, вдруг понадобиться писать свою систему распределения памяти и придется оператор new перегружать :)
505
30 ноября 2007 года
vAC
343 / / 28.02.2006
Не знаю, но я с утечками памяти уже ооочень давно не имел больших проблем.
Во-первых, в 2005 студии неплохо сделан контроль на всякие баги, типа использования не инициализированной переменной, деления на ноль...
Во-вторых сдинамической памятью работаю только через STL или boost. Нужен массив - vector в помощь, указатель на память - полно всяких указателей, и умных и гениальных.
Ну а если уж совсем глухо то можно юзать специальные пакеты для отлова утечек. Работал с линейкой Rational, еще в 6й студии - очень помогла при отлове чужих ошибок, где можно было встретить двойной delete :)
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог