C++ Valgrind: A Practical Memory Debugging Complete Guide
이 글의 핵심
Learn Valgrind for C++: install Memcheck, detect leaks and invalid access, interpret output, use suppressions, and compare tools—with examples and SEO-friendly tips.
Introduction
Valgrind is a powerful toolkit for memory leaks, bugs, and profiling in C/C++ programs. On Linux and macOS it is essential for tracking down memory issues.
1. Installation and basic usage
Installation
# Ubuntu/Debian
sudo apt-get install valgrind
# macOS
brew install valgrind
# Check version
valgrind --version
Basic usage
# Compile (debug symbols)
g++ -g program.cpp -o program
# Run Valgrind
valgrind --leak-check=full ./program
# More detail
valgrind --leak-check=full --show-leak-kinds=all ./program
# Track origins of uninitialized values
valgrind --track-origins=yes ./program
2. Detecting memory leaks
Example 1: Memory leak
// leak.cpp
#include <iostream>
int main() {
int* ptr = new int(42);
std::cout << *ptr << std::endl;
return 0;
}
g++ -g leak.cpp -o leak
valgrind --leak-check=full ./leak
Sample output:
==12345== HEAP SUMMARY:
==12345== in use at exit: 4 bytes in 1 blocks
==12345== total heap usage: 1 allocs, 0 frees, 4 bytes allocated
==12345==
==12345== 4 bytes in 1 blocks are definitely lost
==12345== at 0x4C2E0EF: operator new(unsigned long)
==12345== by 0x400B2C: main (leak.cpp:5)
Example 2: Uninitialized memory
// uninit.cpp
#include <iostream>
int main() {
int x;
if (x > 0) {
std::cout << "positive" << std::endl;
}
return 0;
}
g++ -g uninit.cpp -o uninit
valgrind --track-origins=yes ./uninit
Sample output:
==12345== Conditional jump or move depends on uninitialised value(s)
==12345== at 0x400B2C: main (uninit.cpp:6)
Example 3: Invalid memory access
// invalid.cpp
#include <iostream>
int main() {
int arr[10];
for (int i = 0; i <= 10; ++i) {
arr[i] = i;
}
return 0;
}
g++ -g invalid.cpp -o invalid
valgrind ./invalid
Sample output:
==12345== Invalid write of size 4
==12345== at 0x400B2C: main (invalid.cpp:7)
3. Valgrind tools
Memcheck
valgrind --tool=memcheck ./program
Cachegrind
valgrind --tool=cachegrind ./program
cg_annotate cachegrind.out.12345
Callgrind
valgrind --tool=callgrind ./program
kcachegrind callgrind.out.12345
Helgrind
valgrind --tool=helgrind ./program
Massif
valgrind --tool=massif ./program
ms_print massif.out.12345
4. Common issues
Issue 1: Performance
# Valgrind is very slow (often 10–50×)
# Use only in development/testing
# Test with small inputs
valgrind --leak-check=full ./program < small_input.txt
Issue 2: False positives
# Generate suppression rules
valgrind --gen-suppressions=all ./program > my.supp
# Use suppressions
valgrind --suppressions=my.supp ./program
Example my.supp:
{
<system_library_leak>
Memcheck:Leak
fun:malloc
fun:system_function
}
Issue 3: Missing debug info
# ❌ No debug symbols
g++ program.cpp -o program
valgrind ./program
# ✅ Use -g
g++ -g program.cpp -o program
valgrind ./program
Issue 4: Optimization level
# ❌ Heavy optimization
g++ -O3 -g program.cpp
# ✅ Lower optimization for clearer stacks
g++ -O0 -g program.cpp
5. Interpreting output
Leak kinds
# Definite leak
definitely lost: 100 bytes in 5 blocks
# Indirect leak
indirectly lost: 50 bytes in 2 blocks
# Possible leak
possibly lost: 20 bytes in 1 blocks
# Still reachable at exit
still reachable: 30 bytes in 3 blocks
Quick reference
| Kind | Meaning | Action |
|---|---|---|
| definitely lost | True leak | Fix |
| indirectly lost | Leak via parent pointer | Fix parent leak |
| possibly lost | Possible leak | Investigate |
| still reachable | Still pointed to at exit | Often OK; free on shutdown if strict |
6. Practical examples
Example 1: Smart pointers
// smart_ptr.cpp
#include <memory>
#include <iostream>
int main() {
auto ptr = std::make_unique<int>(42);
std::cout << *ptr << std::endl;
return 0;
}
g++ -g smart_ptr.cpp -o smart_ptr
valgrind --leak-check=full ./smart_ptr
Sample output:
==12345== HEAP SUMMARY:
==12345== in use at exit: 0 bytes in 0 blocks
==12345== total heap usage: 1 allocs, 1 frees, 4 bytes allocated
==12345==
==12345== All heap blocks were freed -- no leaks are possible
Example 2: Vector of raw pointers
// vector_leak.cpp
#include <vector>
#include <iostream>
int main() {
std::vector<int*> vec;
for (int i = 0; i < 5; i++) {
vec.push_back(new int(i));
}
return 0;
}
g++ -g vector_leak.cpp -o vector_leak
valgrind --leak-check=full ./vector_leak
Fix:
// vector_fixed.cpp
#include <vector>
#include <iostream>
int main() {
std::vector<int*> vec;
for (int i = 0; i < 5; i++) {
vec.push_back(new int(i));
}
for (auto ptr : vec) {
delete ptr;
}
return 0;
}
Summary
Key takeaways
- Valgrind: Memory debugging and profiling framework
- Memcheck: Memory error and leak detection
- Cachegrind: Cache profiling
- Helgrind: Threading errors
- Cost: Often 10–50× slower
Tool comparison
| Tool | Purpose | Typical slowdown |
|---|---|---|
| Memcheck | Memory errors | 10–50× |
| Cachegrind | Cache analysis | 20–100× |
| Callgrind | Call graphs | 20–100× |
| Helgrind | Thread errors | 20–50× |
| Massif | Heap profiling | ~20× |
Practical tips
- Compile with
-g - Use
--leak-check=full - Test with small inputs
- Use suppression files for known false positives
- Prefer smart pointers
Next steps
- C++ Sanitizers
- C++ GDB
- C++ memory management
Related posts
Frequently Asked Questions (FAQ)
Q. When would I use this in practice?
A. Learn Valgrind for C++: install Memcheck, detect leaks and invalid access, interpret output, use suppressions, and compa…
Q. What should I read before this?
A. Follow the previous article or related articles links at the bottom of each post to learn in sequence. See the C++ series index for the full picture.
Q. Where can I study this more deeply?
A. Check cppreference and the relevant library’s official documentation. The reference links at the end of the article are also worth using.
Related Articles (Internal Links)
Other articles related to this topic.
- C++ GDB | ‘디버거’ 가이드
- C++ Sanitizers 완벽 가이드 | ASan/TSan/UBSan 사용법 (메모리/스레드 디버깅)
- C++ Allocator | ‘메모리 할당자’ 커스터마이징 가이드
Keywords Covered in This Article (Related Search Terms)
This article covers C++, Valgrind, memory, debugging, tools.