Обнаружение утечек памяти в программах на C?

Если мы хотим проверить утечки памяти в программе на С++, мы можем перегрузить операторы new и delete, чтобы отслеживать выделенную память. Что делать, если мы хотим проверить утечки в программе на C? Так как в C нет перегрузки оператора, можем ли мы переписать указатель функции malloc для перехвата вызовов на malloc и отслеживания выделения памяти? Легче ли использовать внешние утилиты? Пожалуйста, предоставьте некоторый код, поскольку я не знаком с указателями методов записи.

Примечание. Я бы хотел сделать это без каких-либо внешних утилит для практики.

Ответы

Ответ 1

Как и было предложено, для этого уже существуют отличные инструменты, такие как Valgrind.

Далее:

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

#define malloc(X) my_malloc( X, __FILE__, __LINE__, __FUNCTION__)

void* my_malloc(size_t size, const char *file, int line, const char *func)
{

    void *p = malloc(size);
    printf ("Allocated = %s, %i, %s, %p[%li]\n", file, line, func, p, size);

    /*Link List functionality goes in here*/

    return p;
}

Вы поддерживаете Связанный список адресов, которые выделяются вместе с файлом и номером строки из выделенного места. Вы обновляете список ссылок с помощью записей в malloc.

Как и выше, вы можете написать реализацию для free, в которой вы проверяете, какие записи адресов запрашиваются для вашего связанного списка. Если нет соответствующей записи, ее ошибка использования, и вы можете ее пометить.

В конце вашей программы вы печатаете или записываете содержимое связанного списка в файл журнала. Если нет утечек, ваш связанный список не должен иметь записей, но если есть какие-то утечки, тогда файл журнала дает точное местоположение места, где была выделена память.

Обратите внимание, что при использовании этого макрокоманды вы теряете тип проверки, который предлагает функция, но это аккуратный небольшой трюк, который я использую много раз.

Надеюсь, это поможет, и все самое лучшее:)

Ответ 2

Valgrind - это то, что вам нужно.

Я помню, как читал первую главу Алгоритмы в двух словах, в которых говорилось об этом, хотя он не включал код. Просто добавьте в случае, если вам понравится.

так как нет перегрузки оператора в c, мы можем переписать malloc функция для перехвата вызовов в malloc и память треков распределение

Собственно, вы можете. GIve LD_PRELOAD читать.

Ответ 3

В дополнение к ответу @Als, который будет обертывать вызовы в вашем исходном коде, если вы используете gnu ld, вы можете связать компоновщик всех вызовов (предположительно с malloc, realloc, calloc, и free) во время соединения, независимо от того, откуда они взяты. Затем вы пишете __wrap_malloc и т.д. И можете вызвать исходную функцию, например, __real_malloc.

См. --wrap=symbol в http://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_node/ld_3.html

Я не знаю, как это работает с вызовами из разделяемых библиотек. Я предполагаю, что это не так.

Ответ 5

Используйте функцию mallinfo, которая сработала для меня на baremetal Xilinx Zynq, используя Xilinx SDK gcc. Я тестировал с умышленной утечкой памяти - я понятия не имею, почему, но результаты Google были невероятно ужасны при поиске этого решения, распространяющего слово, чтобы помочь другим разработчикам!