0Pricing
C Academy · Урок

Обнаружение утечек

Основы memcheck

«Обнаружение утечек» — бесплатный урок C Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C Academy содержит 4 уроков всего.

Что такое утечка

Утечка памяти возникает, когда вы выделяете память в HEAP с помощью malloc, calloc или realloc, а затем теряете все указатели на неё, не успев вызвать free.

Блок остаётся зарезервированным, но недоступным до завершения процесса. В долго работающих программах утечки накапливаются, пока память не закончится.

Минимальная утечка

Эта программа теряет один блок размером 40 байт.

Указатель p — локальная переменная. Когда main возвращает управление, p исчезает, но блок HEAP, на который он указывал, никогда не освобождается.

#include <stdlib.h>

int main(void) {
    int *p = malloc(10 * sizeof(int));
    p[0] = 1;
    return 0; /* never free(p) */
}

Запуск memcheck

memcheck — инструмент по умолчанию, поэтому его имя можно не указывать.

Добавьте --leak-check=full, чтобы получить стек вызовов для каждого потерянного блока.

gcc -g -O0 -o leak leak.c
valgrind --leak-check=full ./leak

Сводка утечек

При завершении Valgrind выводит LEAK SUMMARY. Для программы выше она выглядит примерно так:

definitely lost: 40 bytes in 1 blocks

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

Четыре категории утечек

memcheck распределяет потерянную память по четырём категориям:

  • definitely lost — указателей больше не осталось; настоящая утечка
  • indirectly lost — доступна только через блок, помеченный как definitely lost
  • possibly lost — остался только указатель на внутреннюю часть блока
  • still reachable — при завершении указатель существует, но вы так и не освободили память

Definitely lost и still reachable

definitely lost — самая срочная категория: эти байты невозможно вернуть, пока программа работает.

still reachable — менее серьёзная проблема. При завершении блок считается потерянным, но глобальный или статический указатель всё ещё ссылается на него. Обычно это означает, что память выделили один раз и просто не позаботились её освободить.

Косвенные утечки

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

Начальный элемент помечается как definitely lost, а остальные — как indirectly lost. Устранение первопричины, то есть потерянного начала, восстанавливает доступ ко всей структуре.

struct Node { int v; struct Node *next; };

struct Node *make(void) {
    struct Node *h = malloc(sizeof *h);
    h->next = malloc(sizeof *h);
    h->next->next = NULL;
    return h;
}
/* if the caller drops the returned head, both nodes leak */

Исправленная версия

Освобождайте всё, что выделяете. В этой версии утечек нет.

Под Valgrind она сообщает: All heap blocks were freed -- no leaks are possible.

#include <stdlib.h>

int main(void) {
    int *p = malloc(10 * sizeof(int));
    p[0] = 1;
    free(p);
    return 0;
}

Подсчёт выделений

Даже при отсутствии утечек HEAP SUMMARY показывает, насколько активно программа использовала память:

total heap usage: 1 allocs, 1 frees, 40 bytes allocated

Если число выделений и освобождений совпадает, выполнение прошло чисто. Несоответствие — первая подсказка, что какой-то блок оказался потерян.

Отображение доступных блоков

По умолчанию memcheck не перечисляет подробно блоки, помеченные как still reachable. Чтобы проверить и их, добавьте:

--show-leak-kinds=all

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

valgrind --leak-check=full --show-leak-kinds=all ./leak

Утечки на путях обработки ошибок

Самые коварные утечки скрываются на путях с досрочным возвратом. В этом случае, если второе выделение памяти завершится ошибкой, первый блок будет потерян.

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

char *a = malloc(100);
char *b = malloc(100);
if (!b) {
    /* bug: a is leaked here */
    return -1;
}
/* fix: free(a); before returning */

Быстрая проверка

Выберите категорию утечек, требующую наиболее срочного внимания.

Итоги

Теперь вы умеете обнаруживать утечки с помощью memcheck:

  • Запускайте valgrind --leak-check=full ./prog для двоичного файла, собранного с -g
  • Читайте LEAK SUMMARY и HEAP SUMMARY
  • В первую очередь исправляйте definitely lost, а затем находите причину косвенных утечек
  • Используйте --show-leak-kinds=all, чтобы проверять блоки, помеченные как still reachable

Далее: недопустимые обращения к памяти.

Часто задаваемые вопросы

Урок «Обнаружение утечек» бесплатный?

Да — полный текст урока «Обнаружение утечек» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C Academy, подпишись на CoddyKit PRO. Курс C Academy содержит 4 уроков всего.

Чему я научусь в уроке «Обнаружение утечек»?

Основы memcheck Ты практикуешь C Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать C Academy?

Предыдущий опыт не требуется. C Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.

Сколько времени занимает урок «Обнаружение утечек»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке C Academy?

Да. Каждый урок C Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Зачем нужен Valgrind
  2. Обнаружение утечек
  3. Недопустимый доступ
  4. Чтение отчётов
← Назад к C Academy