2010-06-06 2 views
11

Какие советы я могу использовать, чтобы избежать утечек памяти в моих приложениях? В моем текущем проекте я использую инструмент «INSURE ++», который обнаруживает утечку памяти и генерирует отчет.Способы избежать утечек памяти в C/C++

Помимо инструмента есть какой-либо способ идентификации утечек памяти и ее преодоления.

+10

Вы используете C или C++? Доступные решения для разных языков совершенно разные. –

+0

Я использую C. Можете ли вы предоставить разрешение для C и C++ – Ankur

+7

@Ankur: Ну, ответ, который имеет смысл для C, не имеет смысла для C++ и наоборот. Управление памятью - это один из битов, которые изменяются на C++. –

ответ

9

Существует три основных способа сделать это.

Первый - не создает утечки памяти в первую очередь. Оборонительные методы программирования здесь неоценимы. См. Это excellent presentation для краткого изложения этих проблем или соответствующей главы в Secure C Coding. Я больше знаком с C, чем с C++, но я понимаю, что C++ smart pointers полезны здесь.

Второй подход статический анализ, который пытается обнаружить ошибки в исходном коде. Оригинальным инструментом в этой категории является lint, который теперь печально устарел. Насколько мне известно, лучшие инструменты являются коммерческими, такими как coverty. Однако, некоторые free tools do exist.

Третий подход заключается в обнаружении утечек памяти во время выполнения, например INSURE ++. Valgrind отлично здесь и очень рекомендуется. Это может помочь поймать ошибки, которые вы уже ввели. Это особенно полезно, если у вас есть набор тестов, который имеет хороший охват кода.

0

Чтобы избежать или обнаружить? Чтобы избежать, сначала обнаружите и попытайтесь понять, где и почему ... Другой способ может быть использованием библиотеки GC, например, the one described here, но могут существовать другие (возможно, лучшие) библиотеки.

2

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

Для первого, вышеупомянутого valgrind или Rational набора инструментов IBM, если у вас есть лицензия на это. Доктор Доббс рекомендовал BoundsChecker Compuware, но это было 2002.

Для позже, см:

C++ idiom to avoid memory leaks?

http://www.cprogramming.com/tutorial/memory_debugging_parallel_inspector.html

http://scottmcpeak.com/memory-errors/

http://www.yolinux.com/TUTORIALS/C++MemoryCorruptionAndMemoryLeaks.html

1

Использование смарт-указатель, такой как std::shared_ptr<t> (C++ 0x), std::tr1::shared_ptr<t> (TR1), или boost::shared_ptr<t>. Конечно, это решение работает только с C++ - вы по своему усмотрению в C.

2

Интеллектуальные указатели могут быть очень полезны в автоматизации учета объектов жизни:

http://ootips.org/yonat/4dev/smart-pointers.html

Где возможно, использовать стек выделяет объекты внутри своих соответствующих областей вместо нового/удалить.

Инструменты, такие как valgrind, имеют некоторые накладные расходы и могут замедлить ваши трассы.Если вы знаете свою кодовую базу и виды утечек, которые, как правило, возникают, вы можете ориентировать определенные классы и проводить более легкие проверки веса (даже просто счет объекта, который вы проверяете против нуля при выходе). Эти облегченные проверки затем могут быть использованы, чтобы побудить вас сделать более обширный сеанс отладки отладки при их запуске.

7

Для C хорошая организация кода помогает. То есть не бросайте вызовы в malloc() и free() по всей вашей кодовой базе. Централизовать их на две функции, тогда у вас есть одна точка для всех проверок. Простейшим может быть подсчет успешных вызовов и проверка на выходе программы, что они сбалансированы.

static unsigned long mymem_count_alloc = 0; 
static unsigned long mymem_count_free = 0; 

void *mymem_alloc (size_t size) 
{ 
    void *p; 

    p = malloc(size); 
    if (p) 
    { 
     mymem_count_alloc++; 
    } 
    else 
     error logging/handling/signaling 

    return (p); 
} 

void mymem_free (void *p) 
{ 
    if (p) 
    { 
     free(p); 
     mymem_count_free++; 
    } 
} 

void mymem_check (void) 
{ 
    if (mymem_count_alloc != mymem_count_free) 
     error alert 
} 

Вы можете продолжить это для разных структур данных. Вы должны выделить память для строки, используйте mystr_alloc и mystr_free. И так далее. Когда утечка обнаружена таким образом, вы можете быстро сузить ее.

+0

+1 в основном для «Для C, хорошая организация кода помогает ...». Лично я бы предпочел не использовать этот точный метод. Я хотел бы использовать непрозрачные структуры данных, заставляя использовать функции для создания/уничтожения каждого конкретного типа данных. Счет будет смещаться в эти структуры данных создавать/уничтожать функции. Для этого вам нужно четко разобраться в своем коде, так как это легко сделать, чтобы он стал беспорядочным. Этого будет достаточно, чтобы поймать много утечек, и valgrind очень хорош в том, что он говорит об ошибках после забора в массивах. –

+0

Сказав, что этот метод по-прежнему будет полезен, но я бы определенно хотел, чтобы его использование было условным: оно заменяет malloc/free для отладочных сборников, но malloc/free используется в сборках релизов. –

+0

@James: Я тоже использую подход create/destroy. Но там функции оболочки для malloc/free, подобные этим, всегда используются, конечно, немного сложнее, чем этот пример. Часть обработки ошибок всегда необходима, и если при вызове библиотечной функции требуется ** всегда **, то она должна либо стать частью самой функции, либо быть помещена в оболочку, если манипуляция с функцией невозможна , в отношении принципа DRY. http://stackoverflow.com/questions/1529679/how-do-you-program-safely-outside-of-a-managed-code-environment/1530581#1530581 – Secure

Смежные вопросы