Способы избежать утечек памяти в C/С++

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

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

Ответ 1

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

Во-первых, не создавать утечки памяти в первую очередь. Оборонительные методы программирования здесь неоценимы. См. отличную презентацию для краткого изложения этих проблем или соответствующей главы в Безопасное кодирование C. Я больше знаком с C, чем с С++, но я понимаю, что здесь полезны С++ умные указатели.

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

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

Ответ 2

Для 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. И так далее. Когда утечка обнаружена таким образом, вы можете быстро сузить ее.

Ответ 3

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

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

Более подробно см. ниже:

Идиома С++, чтобы избежать утечек памяти?

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

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

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

Ответ 4

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

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

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

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

Ответ 5

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

Ответ 6

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