URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 1720
[ Назад ]

Исходное сообщение
"Как определить утечку памяти в прграмме на С++?"

Отправлено Vadim , 28-Май-03 12:03 
Как определить утечку памяти в программе на С++?

Содержание

Сообщения в этом обсуждении
"Как определить утечку памяти в прграмме на С++?"
Отправлено Olej , 28-Май-03 13:16 
>Как определить утечку памяти в программе на С++?

Хороший вопрос ;-) - это один из самых проблеммных вопросов C/C++ (разработчики Java мотивирует этим отказ от прямого управления памятью в синтаксисе языка)... Но тут - 2 вопроса:

1. как определить сам факт утечки памяти?
2. как определить место утечки памяти?

1. в долгосрочно работающей программе это видно по наблюдаемому уменьшению free памяти в системе - но это "не факт" при недостаточно большом времени: могут наблюдаться циклические изменения, связанные просто с работой подсистемы управления памятью в зависимости от OS...

2. никак. Анализировать код программы.
Это и явилось одной из причин создания Java.


"Как определить утечку памяти в программе на С++?"
Отправлено DonkeyHot , 28-Май-03 13:59 
>Это и явилось одной из причин создания Java.
Это явилось причиной широкой распространенности технологии "сборки мусора", наличие которой можно наблюдать почти во всех языках высокого уровня(я не уверен в слове "почти":-).

"Как определить утечку памяти в программе на С++?"
Отправлено Olej , 28-Май-03 14:05 
>>Это и явилось одной из причин создания Java.
>Это явилось причиной широкой распространенности технологии "сборки мусора", наличие которой можно наблюдать
>почти во всех языках высокого уровня(я не уверен в слове "почти":-).
>

Со словом "почти" - всё в порядке...
Всё определяется синтаксическими конструкциями языка:
- невозможно и представить работу LISP без сборки мусора...
- но ... "чисто компилирующие" семантики C/C++ или тот-же давний FORTRAN - так же трудно представить со сборщиком мусора - как корова с седлом...

И потом - всё хорошо в меру: представьте себе приложение в realtime OS (QNX, VxWorks ...) ... со сборщиком мусора: "такое ночью приснится - не проснёшься" (с).



"Как определить утечку памяти в прграмме на С++?"
Отправлено David , 30-Июн-03 03:08 
>Как определить утечку памяти в программе на С++?

Я встречал такой метод:
1. Создаётся глобальная и доступная для всей программы переменная int gMemCounter = 0;
2. Для всех функций, которые выделяют или освобождают память (malloc, free, new, delete, mysql_store_result, mysql_free_result и т.д.) создаются соответсвтующие макросы, которые увеличивают или уменьшают соответственно наш глобальный счётчик на единицу (если прога многопоточная, то надо ещё и мьютекс поюзать), например:
#ifdef DEBUG
#define MALLOC(ptr,size) \
ptr = malloc (size);
pthread_mutex_lock(&gMemMutex); \
gMemCounter++; \
pthread_mutex_unlock(&gMemMutex);
#else
#define MALLOC(ptr,size) ptr = malloc (size);
#endif

3. В самом конце выполнения программы проверяется наш счётчик - он, очевидно, должен быть равен нулю, если это не так, то либо есть утечка, либо мы недостаточно аккуратны.

Этот способ позволяет только определить наличие утечки, но не говорит - где она, у него масса недостатков, но всё же это единственное решение, которое я встречал, и я считаю его вполне применимым.


"Как определить утечку памяти в прграмме на С++?"
Отправлено sol , 30-Июн-03 16:32 
>#ifdef DEBUG
>#define MALLOC(ptr,size) \
>ptr = malloc (size);
>pthread_mutex_lock(&gMemMutex); \
>gMemCounter++; \
>pthread_mutex_unlock(&gMemMutex);
>#else
>#define MALLOC(ptr,size) ptr = malloc (size);
>#endif

Этот макрос в 70% случаев не будет работать корректно. Так, например, для констукции вида
if (condtion)
    MALLOC(ptr, size);

после препроцессирования мы получим (выровненно для наглядности):

if (condition)
    ptr = malloc (size);
pthread_mutex_lock(&gMemMutex);  
gMemCounter++;
pthread_mutex_unlock(&gMemMutex); ;

если условие выполняет - ошибка останется "незамеченной", если же не выполняется - мы увеличим счетчик без  выделения памяти - итог десятки человеко-часов на поиски ошибки выделения памяти.

Думаю правильным было бы использование следующей конструкции:
#ifdef DEBUG
#define MALLOC(ptr,size) do { \
ptr = malloc (size); \
pthread_mutex_lock(&gMemMutex); \
gMemCounter++; \
pthread_mutex_unlock(&gMemMutex); \
while (0)
#else
#define MALLOC(ptr,size) ptr = malloc (size)
#endif


"Как определить утечку памяти в прграмме на С++?"
Отправлено .ChiP. , 30-Июн-03 16:32 
>#ifdef DEBUG
>#define MALLOC(ptr,size) \
>ptr = malloc (size);
>pthread_mutex_lock(&gMemMutex); \
>gMemCounter++; \
>pthread_mutex_unlock(&gMemMutex);
>#else
>#define MALLOC(ptr,size) ptr = malloc (size);
>#endif

Этот макрос в 70% случаев не будет работать корректно. Так, например, для констукции вида
if (condtion)
    MALLOC(ptr, size);

после препроцессирования мы получим (выровненно для наглядности):

if (condition)
    ptr = malloc (size);
pthread_mutex_lock(&gMemMutex);  
gMemCounter++;
pthread_mutex_unlock(&gMemMutex); ;

если условие выполняет - ошибка останется "незамеченной", если же не выполняется - мы увеличим счетчик без  выделения памяти - итог десятки человеко-часов на поиски ошибки выделения памяти.

Думаю правильным было бы использование следующей конструкции:
#ifdef DEBUG
#define MALLOC(ptr,size) do { \
ptr = malloc (size); \
pthread_mutex_lock(&gMemMutex); \
gMemCounter++; \
pthread_mutex_unlock(&gMemMutex); \
while (0)
#else
#define MALLOC(ptr,size) ptr = malloc (size)
#endif


"Как определить утечку памяти в прграмме на С++?"
Отправлено David , 30-Июн-03 17:57 
>
>Думаю правильным было бы использование следующей конструкции:
>#ifdef DEBUG
>#define MALLOC(ptr,size) do { \
>ptr = malloc (size); \
>pthread_mutex_lock(&gMemMutex); \
>gMemCounter++; \
>pthread_mutex_unlock(&gMemMutex); \
>while (0)
>#else
>#define MALLOC(ptr,size) ptr = malloc (size)
>#endif

:)
Респект абсолютный и полный, но недочёт есть и тут :) - do while - абсолютно лишне. Окончательный вариант:
#ifdef DEBUG
#define MALLOC(ptr,size) { \
ptr = malloc (size); \
pthread_mutex_lock(&gMemMutex); \
gMemCounter++; \
pthread_mutex_unlock(&gMemMutex); \
}
#else
#define MALLOC(ptr,size) ptr = malloc (size)
#endif

Прошу отметить, что суть вопроса не в правильности составления макроса, а в принципе определения утечки :)


"Как определить утечку памяти в прграмме на С++?"
Отправлено pth , 30-Июн-03 18:27 
>Респект абсолютный и полный, но недочёт есть и тут :) - do
>while - абсолютно лишне.

Оно необходимо. В твоей версии при

if(...)
    MALLOC(p, s);
else
    ....;

получится фигня.

>#else
>#define MALLOC(ptr,size) ptr = malloc (size)

#define MALLOC(ptr,size) (ptr = malloc(size))

>#endif

P.S. А по теме - FAQ из ru.unix.prog.


"Как определить утечку памяти в прграмме на С++?"
Отправлено David , 01-Июл-03 12:31 
>Оно необходимо. В твоей версии при
>
>if(...)
>    MALLOC(p, s);
>else
>    ....;
>
>получится фигня.

Согласен, был не прав :) Но для меня это не критично -я считаю хорошим стилем ставить везде скобки явно.
Спасибо за наводку, нашёл много полезных вещей. Вот ссылки:
http://bsd.opennet.ru/base/faq/prog_faq.txt.html
http://mifi3.pp.ru/howto/C++Programming-HOWTO-11.html

Во FreeBSD-портах накопал следующее:
devel/boehm-gc           http://www.hpl.hp.com/personal/Hans_Boehm/gc/
devel/dmalloc            http://dmalloc.com/docs/5.2.0/online/dmalloc.html
devel/mprof
devel/uds                http://frost.flewid.de/uds/
Сам пока не юзал, но судя по описанию - очень даже ничего.


"Как определить утечку памяти в прграмме на С++?"
Отправлено Миша , 30-Май-05 19:05 
можно сделать два счетчика,
gMemCounter = 0;
gMemPlace = 0;

и если у тебя gMemCounter будет инкрементироваться на единицу при каждом выделении памяти, то gMemPlace на 2 в степени gMemCounter. в случае утечки получишь точное место

>>Как определить утечку памяти в программе на С++?
>
>Я встречал такой метод:
>1. Создаётся глобальная и доступная для всей программы переменная int gMemCounter =
>0;
>2. Для всех функций, которые выделяют или освобождают память (malloc, free, new,
>delete, mysql_store_result, mysql_free_result и т.д.) создаются соответсвтующие макросы, которые увеличивают или
>уменьшают соответственно наш глобальный счётчик на единицу (если прога многопоточная, то
>надо ещё и мьютекс поюзать), например:
>#ifdef DEBUG
>#define MALLOC(ptr,size) \
>ptr = malloc (size);
>pthread_mutex_lock(&gMemMutex); \
>gMemCounter++; \
>pthread_mutex_unlock(&gMemMutex);
>#else
>#define MALLOC(ptr,size) ptr = malloc (size);
>#endif
>
>3. В самом конце выполнения программы проверяется наш счётчик - он, очевидно,
>должен быть равен нулю, если это не так, то либо есть
>утечка, либо мы недостаточно аккуратны.
>
>Этот способ позволяет только определить наличие утечки, но не говорит - где
>она, у него масса недостатков, но всё же это единственное решение,
>которое я встречал, и я считаю его вполне применимым.



"Как определить утечку памяти в прграмме на С++?"
Отправлено Арлекин , 30-Июн-03 08:51 
Ищи на
http://citforum.ru
там где-то что-то было, но, насколько я помню (давно смотрел), как-то своеобразно...

"там где-то что-то было, но,"
Отправлено cool_hacker , 01-Июл-03 17:11 
а у нас взяли недавно на работу "интернет-оператора"
ходит девочка по чатам и где попало такие вот с-с-сылочки расставляет для рекламы с-с-с-айта
А, Арлекин, признайся честно!
мучают меня подозрения :-))))

"там где-то что-то было, но,"
Отправлено Арлекин , 02-Июл-03 08:43 
:) Подозрения мучают мусарню. Из тебя, детка, девочка еще может и получится, а я староват уже.

"Как определить утечку памяти в прграмме на С++?"
Отправлено asso , 02-Июл-03 11:37 
>Как определить утечку памяти в программе на С++?

Рекомендую valgrind:  http://developer.kde.org/~sewardj/