Перейти к содержанию

Последнее обновление:2026-10-12

Обнаружение утечек памяти в C++

C++那些事: как проверять память

При написании кода на C/C++ проблемы с памятью подстерегают повсюду: и в работе, и на собеседованиях не обойтись без темы памяти.

Сегодня на примере Step by Step освоим проверку памяти C++ с помощью valgrind.

Смоделируем три проблемы:

  • обнаружение проблем с освобождением памяти
  • обнаружение выхода за границы при записи
  • обнаружение выхода за границы при чтении

Вы научитесь:

  • как обнаруживать эти три проблемы
  • как использовать gdb + valgrind вместе для отладки

Добро пожаловать к обсуждению.

1. Введение примера

Взгляните на следующий код — в нём много проблем:

  • strcpy небезопасен: каков бы ни был размер памяти, возможен выход за границы
  • при print происходит обращение за границы msg
  • деструктор не освобождает память

Узнали свой старый код, да? Ха-ха.

В этом разделе и найдём эти проблемы.

class Message {
private:
    char *msg;

public:
    Message(const char *text) {
        msg = new char[3];
        std::strcpy(msg, text);
    }

    void printOutOfRange() {
        std::cout << msg[5] << std::endl;
    }

    ~Message() {

    }
};

int main() {
    Message message("hello");
    message.printOutOfRange();

    return 0;
}

2. valgrind

Установка valgrind:

brew install valgrind // mac
sudo apt-get install install // ubuntu
Установка для других систем — см. официальный сайт:

https://valgrind.org/downloads/

3. Использование

Сначала при компиляции рекомендуется использовать debug, -g — так можно будет определить, в какой строке кода проблема.

g++ val_test.cc -g
Затем выполняем:

valgrind --leak-check=full ./a.out 
И получаем информацию от valgrind:

detect

Здесь мы видим несколько проблем:

  • Invalid write

Происходит в val_test.cc::11

  • Invalid read

Происходит в val_test.cc:10

  • утечка памяти

1 allocs, 0 frees, 3 bytes allocated.

Эта информация позволяет быстро определить, в какой строке кода проблема.

4. Отладка с помощью gdb

Если добавить --vgdb-error=0, можно удобно отлаживать код: идём по шагам и смотрим, где проблема.

valgrind --leak-check=full --vgdb-error=0 ./a.out 
attach

Затем подключаемся gdb

gdb -q a.out
Вставляем в gdb строку target из вывода выше, затем continue — и мы увидим код соответствующей строки, а valgrind продолжит выводить информацию.

gdb

continue

В этом разделе мы на практике разобрали проблемы с памятью; если было полезно — делитесь с друзьями.

Похожие темы

Комментарии