Обнаружение утечек памяти в программах на C? - PullRequest
22 голосов
/ 31 января 2012

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

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

Ответы [ 5 ]

43 голосов
/ 31 января 2012

Как уже предлагалось, для этого уже существуют отличные инструменты, такие как 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, в которой вы проверяете записи адресов, которые просят освободить, в вашем связанном списке.Если соответствующей записи нет, это ошибка использования, и вы можете пометить ее так.

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

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

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

12 голосов
/ 31 января 2012

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

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

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

На самом деле, вы можете. Дайте LD_PRELOAD чтение.

4 голосов
/ 31 января 2012

В дополнение к ответу @ 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

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

2 голосов
/ 03 мая 2017

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

1 голос
/ 15 июля 2015

Вот как вы можете изменить malloc, бесплатные хуки: Хуки для Malloc

...