Большой Воронежский Форум
Страница 1 из 3
1 23 >
» Программирование>Эффективная утилитка для обнаружения утечек памяти и run-time ошибок
Наиль 21:14 01.09.2010
Привет всем!
Созданная прога работает ооооочень медленно, похоже, что там много утечек памяти, потому что используется множество указателей. Подскажите, пожалуйста, какую-нибудь эффективную утилитку для поиска утечек памяти и run-time ошибок в Visual Studio C++. Спасибо. [Ответ]
Part!zan 21:39 01.09.2010

Сообщение от Наиль:
прога работает ооооочень медленно, похоже, что там много утечек памяти, потому что используется множество указателей

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

Сообщение от Наиль:
эффективную утилитку для поиска утечек памяти

Automated QA AQtime [Ответ]
The_God 21:53 01.09.2010
http://en.wikipedia.org/wiki/BoundsChecker [Ответ]
Spectator 22:26 01.09.2010

Сообщение от Наиль:
Привет всем!
Созданная прога работает ооооочень медленно, похоже, что там много утечек памяти, потому что используется множество указателей. Подскажите, пожалуйста, какую-нибудь эффективную утилитку для поиска утечек памяти и run-time ошибок в Visual Studio C++. Спасибо.

В Visual Studio утечки памяти фиксируются при завершении работы отлаживаемой программы.
Равно как и run-time ошибки фиксируются прямо в run-time))
А вот "множество указателей" придется искать самостоятельно) [Ответ]
Part!zan 22:35 01.09.2010

Сообщение от Spectator:
В Visual Studio утечки памяти фиксируются при завершении работы отлаживаемой программы

Нифига подобного. Утечки студия не фиксирует. Оверраны-андерраны, но не утечки. [Ответ]
Spectator 00:09 02.09.2010

Сообщение от Part!zan:
Нифига подобного. Утечки студия не фиксирует. Оверраны-андерраны, но не утечки.

Все версии, кроме Express. [Ответ]
Part!zan 19:09 02.09.2010
Spectator, специально проверил. VS2005 Pro. Утечки не ловятся. Написал убер-программу. Выполнилась без сучка и задоринки.
Код:
#include <stdlib.h>

char* a;

int main(){

a=(char*)malloc(10000);

a[0]=0;

return 0;
}
[Ответ]
Hopkroft 06:51 03.09.2010

Сообщение от :
не вижу связи. прога может не иметь утечек памяти и работать медленно, а может иметь и работать быстро.

+1.
Хотя...если он выделяет нууу очень огромное количество памяти, то операционка может начать использовать файл подкачки. Из-за этого могут быть тормоза.

Сообщение от :
Automated QA AQtime

Опередил. Тоже самое хотел ему посоветовать. Себе поставил версию AutomatedQA AQTime v6.21.400.86. В VS 2008 интегрировалась без проблем. [Ответ]
Spectator 09:00 03.09.2010

Сообщение от Part!zan:
Spectator, специально проверил. VS2005 Pro. Утечки не ловятся. Написал убер-программу. Выполнилась без сучка и задоринки.

Код:
#include <stdlib.h>

char* a;

int main(){

a=(char*)malloc(10000);

a[0]=0;

return 0;
}

Всё верно, не надо пользоваться malloc, это функция устарела еще в 90х (это наследие языка C). Там обвертка в DEBUG версии для new/delete, которая, собственно, и фиксирует утечки. [Ответ]
Spectator 09:06 03.09.2010

Сообщение от Hopkroft:
+1.
Хотя...если он выделяет нууу очень огромное количество памяти, то операционка может начать использовать файл подкачки. Из-за этого могут быть тормоза.

Неверная логика. Пока вы программу отлаживаете по 10 минут за сессию, утечки будут небольшими, и вы их воздействия на работу программы не заметите. Когда реальный пользователь будет работать с программой по 8 часов, ситуация будет в корне иной.

Сообщение от Hopkroft:
Опередил. Тоже самое хотел ему посоветовать. Себе поставил версию AutomatedQA AQTime v6.21.400.86. В VS 2008 интегрировалась без проблем.

Говорят, хорошая штука. Надо поставить, наконец. Но, повторюсь, конкретно утечки памяти фиксируются и самой VS отлично. [Ответ]
aerin 11:25 03.09.2010

Сообщение от Spectator:
Всё верно, не надо пользоваться malloc, это функция устарела еще в 90х (это наследие языка C). Там обвертка в DEBUG версии для new/delete, которая, собственно, и фиксирует утечки.

А позырить исходники crt религия не позволяет? malloc.c из MS VC 2010:
Код:
/***
*malloc.c - Get a block of memory from the heap
*
*       Copyright (c) Microsoft Corporation. All rights reserved.
*
*Purpose:
*       Defines the malloc() function.
*
*******************************************************************************/

#include <cruntime.h>
#include <malloc.h>
#include <internal.h>
#include <mtdll.h>
#include <dbgint.h>
#include <rterr.h>

#include <windows.h>
#include <winheap.h>
#include <rtcsup.h>

extern int _newmode;    /* malloc new() handler mode */

#ifdef _DEBUG
#define _heap_alloc _heap_alloc_base
#endif  /* _DEBUG */

/***
*void *_heap_alloc_base(size_t size) - does actual allocation
*
*Purpose:
*       Same as malloc() except the new handler is not called.
*
*Entry:
*       See malloc
*
*Exit:
*       See malloc
*
*Exceptions:
*
*******************************************************************************/

__forceinline void * __cdecl _heap_alloc (size_t size)

{

    if (_crtheap == 0) {
        _FF_MSGBANNER();    /* write run-time error banner */
        _NMSG_WRITE(_RT_CRT_NOTINIT);  /* write message */
        __crtExitProcess(255);  /* normally _exit(255) */
    }

    return HeapAlloc(_crtheap, 0, size ? size : 1);
}


/***
*void *malloc(size_t size) - Get a block of memory from the heap
*
*Purpose:
*       Allocate of block of memory of at least size bytes from the heap and
*       return a pointer to it.
*
*       Calls the new appropriate new handler (if installed).
*
*Entry:
*       size_t size - size of block requested
*
*Exit:
*       Success:  Pointer to memory block
*       Failure:  NULL (or some error value)
*
*Uses:
*
*Exceptions:
*
*******************************************************************************/

void * __cdecl _malloc_base (size_t size)
{
    void *res = NULL;

    //  validate size
    if (size <= _HEAP_MAXREQ) {
        for (;;) {

            //  allocate memory block
            res = _heap_alloc(size);

            //  if successful allocation, return pointer to memory
            //  if new handling turned off altogether, return NULL

            if (res != NULL)
            {
                break;
            }
            if (_newmode == 0)
            {
                errno = ENOMEM;
                break;
            }

            //  call installed new handler
            if (!_callnewh(size))
                break;

            //  new handler was successful -- try to allocate again
        }
    } else {
        _callnewh(size);
        errno = ENOMEM;
        return NULL;
    }

    RTCCALLBACK(_RTC_Allocate_hook, (res, size, 0));
    if (res == NULL)
    {
        errno = ENOMEM;
    }
    return res;
}
[Ответ]
Spectator 14:38 03.09.2010

Сообщение от aerin:
А позырить исходники crt религия не позволяет? malloc.c из MS VC 2010:

Я специально проверил, в VS2008 без каких-либо специальных #define ликов не было.
Собственно, вот
The C++ _set_new_mode function sets the new handler mode for malloc.The new handler mode indicates whether, on failure, malloc is to call the new handler routine as set by _set_new_handler.By default, malloc does not call the new handler routine on failure to allocate memory.You can override this default behavior so that, when malloc fails to allocate memory, malloc calls the new handler routine in the same way that the new operator does when it fails for the same reason.To override the default, call....
Из этого следует что надо вызвать специальную ф-ю _set_new_mode для того чтобы это заработало. Извращение.
Не заглянул я сразу не потому что "слабо", а потому что malloc и иже с ней - устарели. [Ответ]
Akad 17:14 03.09.2010
Несколько раз порывался что-нибудь поотлаживать с помощью AQtime, каждый обходился стандартными средствами студии.
А те, кто использует malloc вместо new, указатели на com вместо CComPrt и прочая, по русски говоря - сам себе злобный Буратино. Или иначе выражаясь - учите мат. часть, а не усложняйте себе жизнь. [Ответ]
Spectator 19:00 03.09.2010

Сообщение от Akad:
Несколько раз порывался что-нибудь поотлаживать с помощью AQtime, каждый обходился стандартными средствами студии.

Я тоже не стал прикручивать, думаю основные клиенты AQTime - пользователи CodeGear и остального трэша от Borland/Inprise. Там от версии к версии растут требования и ненужные навороты, а про такие фундаментальные вещи они забывают. Впрочем, типичный пользователь CodeGear на утечки памяти забивает. Ентож RAD - сляпал, заработало и зашибись. Информация об утечках будет лишь отвлекать от творческого процесса накидывания компонент)))

Сообщение от Akad:
А те, кто использует malloc вместо new, указатели на com вместо CComPrt и прочая, по русски говоря - сам себе злобный Буратино. Или иначе выражаясь - учите мат. часть, а не усложняйте себе жизнь.

Именно так. Вообще всегда надо использовать для одной задачи одну функцию (оператор). В данном случае для C++ это должен быть new (и соответственно delete). А некоторые умники умудряются выделять new, а удалять через free))) Но в VC думаю в Debug режиме этот фокус не пройдет. [Ответ]
Hopkroft 19:08 03.09.2010

Сообщение от :
Неверная логика. Пока вы программу отлаживаете по 10 минут за сессию, утечки будут небольшими, и вы их воздействия на работу программы не заметите. Когда реальный пользователь будет работать с программой по 8 часов, ситуация будет в корне иной.

Какая ещё неверная логика? Логика либо есть либо её нету.
Лично видел пример который описал в раскритикованном посте Сам бы не видел, не стал бы говорить. Правда там машина была древняя.
Случаи когда бывают тормоза при выделении памяти бывают разные. И каждый случай нужно разбирать. В каком то случае это ваши сессии, в каком-то случае постоянное выделение/освобождение большого участка памяти. Может быть и утечка из-за "забытых" указателей. Ну или какой-нибудь экстремальный, по типу битой аппаратки.
[Ответ]
Spectator 19:21 03.09.2010

Сообщение от Hopkroft:
Какая ещё неверная логика? Логика либо есть либо её нету.

Не совсем так)

Сообщение от Hopkroft:
Лично видел пример который описал в раскритикованном посте Сам бы не видел, не стал бы говорить. Правда там машина была древняя.
Случаи когда бывают тормоза при выделении памяти бывают разные. И каждый случай нужно разбирать. В каком то случае это ваши сессии, в каком-то случае постоянное выделение/освобождение большого участка памяти. Может быть и утечка из-за "забытых" указателей. Ну или какой-нибудь экстремальный, по типу битой аппаратки.

Не надо ничего разбирать, нужно просто удалять память. Я просто ВСЕГДА сразу после выделения пишу удаление в нужном месте. А потом уже приступаю к коду, который с этой памятью работает. Или наоборот, сначала код как будто бы память уже выделена и переменная объявлена, а потом - new/delete.
Это позволяет избежать 99% утечек.
[Ответ]
Part!zan 19:29 03.09.2010

Сообщение от Spectator:
Там обвертка в DEBUG версии для new/delete, которая, собственно, и фиксирует утечки.

Ну, начались отмазки... Сначала VS все утечки фиксировала, теперь - только которые созданы с new. Что дальше? А если я апишные функции для выделения памяти использую?
Ниче VS не фиксирует. Сделал версию 2.0, с new. VS2005 гордо промолчала.

Сообщение от :
char* a;

int main(){

a= new char[10000];

a[0]=0;

return 0;
}

Так что, не все так радужно.

Сообщение от Spectator:
malloc и иже с ней - устарели

С какой стати они устарели? Просто программеры обленились. К тому же new есть только в плюсах.

Сообщение от Spectator:
Когда реальный пользователь будет работать с программой по 8 часов, ситуация будет в корне иной

Далеко не факт, что утечки вызовут замедление программы. В общем случае, нельзя судить по скорости выполнения о наличии утечек. [Ответ]
Spectator 19:42 03.09.2010

Сообщение от Part!zan:
Ну, начались отмазки...

Какие "отмазки"? Еще раз: в ОТЛАДОЧНОЙ Debug версии в СТАНДАРТНОМ проекте (без собственных плясок с бубном) все NEW и DELETE (но не malloc'и) имеют обвертку, которая ПРИ ВЫХОДЕ из программы позволяет Visual Studio создать и показать dump всех не удаленных блоков памяти.

Сообщение от Part!zan:
А если я апишные функции для выделения памяти использую?

Тогда Visual Studio утечки не зафиксирует. Здесь и AQTime наверняка не поможет.

Сообщение от Part!zan:
Ниче VS не фиксирует. Сделал версию 2.0, с new. VS2005 гордо промолчала.

В отладочном режиме запусти. Студия, надеюсь, не Express Edition? Там этот функционал выпилен, хотя можно его добавить "ручками". [Ответ]
Hopkroft 19:45 03.09.2010

Сообщение от Spectator:
Я просто ВСЕГДА сразу после выделения пишу удаление в нужном месте. А потом уже приступаю к коду, который с этой памятью работает.

Это в идеальном варианте, но часто если нужно использовать какой-то хитрый механизм. Подгружать в память новые объёмы данных, или изменять размер буфера то тут возможны ошибки. [Ответ]
Part!zan 20:00 03.09.2010

Сообщение от Spectator:
Какие "отмазки"?

Сообщение от Spectator:
В Visual Studio утечки памяти фиксируются при завершении работы отлаживаемой программы.

Сообщение от Spectator:
в ОТЛАДОЧНОЙ Debug версии в СТАНДАРТНОМ проекте (без собственных плясок с бубном) все NEW и DELETE (но не malloc'и) имеют обвертку, которая ПРИ ВЫХОДЕ из программы позволяет Visual Studio создать и показать dump всех не удаленных блоков памяти

Вот такие отмазки. Аккуратнее надо в своих утверждениях быть.

Сообщение от Spectator:
В отладочном режиме запусти. Студия, надеюсь, не Express Edition? Там этот функционал выпилен, хотя можно его добавить "ручками"

Отладочный режим, студия 2005 про. Сами по себе утечки НЕ ловятся. Никакие. Для "улова" нужны доп. усилия. Как видно из статьи, маллок ни при чем. [Ответ]
Spectator 20:07 03.09.2010

Сообщение от Hopkroft:
Это в идеальном варианте, но часто если нужно использовать какой-то хитрый механизм. Подгружать в память новые объёмы данных, или изменять размер буфера то тут возможны ошибки.

Безусловно, но в тех случаях когда можно так сделать - лучше так делать. А когда "извращаешься" - тщательно проверить с отладчиком хотя бы сразу после написания. Это не гарантия, но необходимая мера. Впрочем, если использовать перегруженные new и delete в отладочной версии VS - это ОЧЕНЬ сильно облегчает жизнь. Если ты знаешь что код выполнился и утечек нет - значит все ок на 99%. [Ответ]
Spectator 20:19 03.09.2010

Сообщение от Part!zan:
Отладочный режим, студия 2005 про. Сами по себе утечки НЕ ловятся. Никакие. Для "улова" нужны доп. усилия. Как видно из статьи, маллок ни при чем.

Читаем внимательно:

If you do not use the #define _CRTDBG_MAPALLOC statement, the memory leak dump would look like this:
Copy

Detected memory leaks!
Dumping objects ->
{18} normal block at 0x00780E80, 64 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.

Этот define просто для того чтобы вывод "ликов" был более осмысленным.

Таким:
Detected memory leaks!
Dumping objects ->
C:\PROGRAM FILES\VISUAL STUDIO\MyProjects\leaktest\leaktest.cpp(20) : {18}
normal block at 0x00780E80, 64 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.


Кстати, я руками этот дефайн в проекте, с которым сейчас работаю, точно не прописывал. Но информация у меня выдается с именем файла и номером строки.


А вот для того чтобы включить подобный функционал для malloc и free, как раз дополнительные усилия нужны

By including crtdbg.h, you map the malloc and free functions to their debug versions, _malloc_dbg and _free_dbg, which keep track of memory allocation and deallocation. This mapping occurs only in a debug build (in which _DEBUG is defined). Release builds use the ordinary malloc and free functions. [Ответ]
Part!zan 20:24 03.09.2010

Сообщение от Spectator:
Читаем внимательно:

Ага. Читаем еще более внимательно:

Сообщение от :
To enable the debug heap functions, include the following statements in your program:

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

Причем обязательно нужно вставлять вызовы _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_CRTDBG_LEAK_C HECK_DF). и _CrtDumpMemoryLeaks(). Без них нифига об утечках не сообщается. [Ответ]
aerin 21:18 03.09.2010
Spectator, кстати по поводу устаревшего malloc-а. Файл new.cpp:
Код:
/***
*new.cxx - defines C++ new routine
*
*       Copyright (c) Microsoft Corporation.  All rights reserved.
*
*Purpose:
*       Defines C++ new routine.
*
*******************************************************************************/


#ifdef _SYSCRT
#include <cruntime.h>
#include <crtdbg.h>
#include <malloc.h>
#include <new.h>
#include <stdlib.h>
#include <winheap.h>
#include <rtcsup.h>
#include <internal.h>

void * operator new( size_t cb )
{
    void *res;

    for (;;) {

        //  allocate memory block
        res = _heap_alloc(cb);

        //  if successful allocation, return pointer to memory

        if (res)
            break;

        //  call installed new handler
        if (!_callnewh(cb))
            break;

        //  new handler was successful -- try to allocate again
    }

    RTCCALLBACK(_RTC_Allocate_hook, (res, cb, 0));

    return res;
}
#else  /* _SYSCRT */

#include <cstdlib>
#include <new>

_C_LIB_DECL
int __cdecl _callnewh(size_t size) _THROW1(_STD bad_alloc);
_END_C_LIB_DECL

void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
        {       // try to allocate size bytes
        void *p;
        while ((p = malloc(size)) == 0)
                if (_callnewh(size) == 0)
                {       // report no memory
                static const std::bad_alloc nomem;
                _RAISE(nomem);
                }

        return (p);
        }

/*
 * Copyright (c) 1992-2002 by P.J. Plauger.  ALL RIGHTS RESERVED.
 * Consult your license regarding permissions and restrictions.
 V3.13:0009 */
#endif  /* _SYSCRT */
Ничего не напоминает? [Ответ]
Spectator 21:34 03.09.2010

Сообщение от Part!zan:
Ага. Читаем еще более внимательно:

Причем обязательно нужно вставлять вызовы _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_CRTDBG_LEAK_C HECK_DF). и _CrtDumpMemoryLeaks(). Без них нифига об утечках не сообщается.

Вот специально создал НОВЫЙ проект в VS2008 (Professional Edition)
Изменил код конструктора на следующий:

CTestMemApp::CTestMemApp()
{
// TODO: добавьте код создания,
// Размещает весь важный код инициализации в InitInstance
new char[1024];
}

результат в Output при выходе из программы:


Detected memory leaks!
Dumping objects ->
c:\documents and settings\*****\мои документы\visual studio 2008\projects\testmem\testmem\testmem.cpp(26) : {104} normal block at 0x0033C538, 1024 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD

("звездочки", понятно, моих рук дело)
Двойной клик по строке переместил указатель на строку
new char[1024];

Не фантазируйте. Проверяйте свои мысли хоть, прежде чем голословно утверждать на основании статьи из MSDN, которую ВЫ ПРОСТО НЕ ПОНЯЛИ. В ней то все расписано досконально, за что Microsoft и любим. [Ответ]
Spectator 21:44 03.09.2010

Сообщение от aerin:
Spectator, кстати по поводу устаревшего malloc-а. Файл new.cpp:
Ничего не напоминает?

Вы не обратили внимание на:
#ifdef _SYSCRT
[Ответ]
aerin 21:53 03.09.2010
Spectator, и что? В обоих случаях вызывается либо явно, либо внутри malloc (см. ветку else) HeapAlloc(). [Ответ]
Part!zan 22:05 03.09.2010

Сообщение от Spectator:
Не фантазируйте

Я, в отличие от тебя, проверяю, перед тем как что-то написать. У меня все работает так, как написано в мсдн. Возможно, в VS2008 это поведение изменилось.
Кстати, было было очень интересно, если бы ты создал пустой проект Win32 (не MFC и прочее), вставил туда мою убер-прогу и отписался, что у тебя получилось. Чего там напихано в шаблоне проекта - хз. Возможно, что и вышеуказанная инициализация там есть.

Сообщение от Spectator:
Вы не обратили внимание на:

Что new, что malloc работают единообразно. Куча у них одна, никто в здравом уме не будет писать для этого разные функции. [Ответ]
Spectator 22:17 03.09.2010

Сообщение от aerin:
Spectator, и что? В обоих случаях вызывается либо явно, либо внутри malloc (см. ветку else) HeapAlloc().

ок. Я соглашусь что malloc - не устаревшая функция. Почему я ее привел - потому что она по моей памяти смешалась с calloc и прочими... Не использую я *alloc уже десять лет как просто)
realloc только использовал недавно (лет пять назад ))) ) [Ответ]
Spectator 22:20 03.09.2010

Сообщение от Part!zan:
Я, в отличие от тебя, проверяю, перед тем как что-то написать. У меня все работает так, как написано в мсдн. Возможно, в VS2008 это поведение изменилось.

Назови полностью версию твоей студии, включая регалии типа "Express", "Standart", "Professional".
Просто зайди в About.

Сообщение от Part!zan:
Кстати, было было очень интересно, если бы ты создал пустой проект Win32 (не MFC и прочее), вставил туда мою убер-прогу и отписался, что у тебя получилось.

То же, что и у тебя, конечно, это макросы (define'ы), специфические для MFC проектов. Хотя их и вручную можно подключить к "пустым проектам Win32". [Ответ]
Страница 1 из 3
1 23 >
Вверх