Проверка на утечки памяти
На этом шаге вы узнаете, как обнаруживать и предотвращать утечки памяти в C++ с помощью Valgrind, мощного инструмента для отладки памяти. Утечки памяти возникают, когда динамически выделенная память не освобождается правильно, что приводит к тому, что ваша программа потребляет все больше и больше памяти.
Сначала установите Valgrind в терминале:
sudo apt update
sudo apt install -y valgrind
Создайте пример утечки памяти в WebIDE, создав файл memory_leak.cpp в директории ~/project:
touch ~/project/memory_leak.cpp
Добавьте следующий код в файл memory_leak.cpp:
#include <iostream>
class Resource {
public:
Resource(int value) : data(value) {
std::cout << "Resource created: " << data << std::endl;
}
~Resource() {
std::cout << "Resource destroyed: " << data << std::endl;
}
private:
int data;
};
void createMemoryLeak() {
// This creates a memory leak because the resource is not deleted
Resource* leak = new Resource(42);
// Missing: delete leak;
}
int main() {
// Simulate multiple memory leaks
for (int i = 0; i < 3; ++i) {
createMemoryLeak();
}
return 0;
}
Скомпилируйте программу с символами отладки:
g++ -g memory_leak.cpp -o memory_leak
Запустите Valgrind для обнаружения утечек памяти:
valgrind --leak-check=full./memory_leak
Пример вывода Valgrind:
==1988== Memcheck, a memory error detector
==1988== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1988== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==1988== Command:./memory_leak
==1988==
Resource created: 42
Resource created: 42
Resource created: 42
==1988==
==1988== HEAP SUMMARY:
==1988== in use at exit: 12 bytes in 3 blocks
==1988== total heap usage: 5 allocs, 2 frees, 73,740 bytes allocated
==1988==
==1988== 12 bytes in 3 blocks are definitely lost in loss record 1 of 1
==1988== at 0x4849013: operator new(unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==1988== by 0x109241: createMemoryLeak() (memory_leak.cpp:19)
==1988== by 0x109299: main (memory_leak.cpp:26)
==1988==
==1988== LEAK SUMMARY:
==1988== definitely lost: 12 bytes in 3 blocks
==1988== indirectly lost: 0 bytes in 0 blocks
==1988== possibly lost: 0 bytes in 0 blocks
==1988== still reachable: 0 bytes in 0 blocks
==1988== suppressed: 0 bytes in 0 blocks
==1988==
==1988== For lists of detected and suppressed errors, rerun with: -s
==1988== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Как вы можете видеть, Valgrind обнаружил утечку памяти в размере 12 байт в 3 блоках. Объект Resource, созданный в функции createMemoryLeak(), не был удален, что привело к утечке памяти.
Чтобы исправить утечку памяти, измените код так, чтобы правильно удалять ресурсы:
void createMemoryLeak() {
// Properly delete the dynamically allocated resource
Resource* leak = new Resource(42);
delete leak; // Add this line to prevent memory leak
}
Скомпилируйте и запустите программу снова с Valgrind, чтобы убедиться, что утечка памяти исправлена:
g++ -g memory_leak.cpp -o memory_leak
valgrind --leak-check=full./memory_leak
==2347== Memcheck, a memory error detector
==2347== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==2347== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==2347== Command:./memory_leak
==2347==
Resource created: 42
Resource destroyed: 42
Resource created: 42
Resource destroyed: 42
Resource created: 42
Resource destroyed: 42
==2347==
==2347== HEAP SUMMARY:
==2347== in use at exit: 0 bytes in 0 blocks
==2347== total heap usage: 5 allocs, 5 frees, 73,740 bytes allocated
==2347==
==2347== All heap blocks were freed -- no leaks are possible
==2347==
==2347== For lists of detected and suppressed errors, rerun with: -s
==2347== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Основные моменты о утечках памяти:
- Всегда освобождайте динамически выделенную память с помощью
delete
- Используйте умные указатели, такие как
unique_ptr и shared_ptr
- Используйте Valgrind для обнаружения утечек памяти
- Компилируйте с флагом
-g для получения более подробной информации для отладки