Pointers and Memory Management
Memory Leaks
Detecting, understanding, and preventing memory leaks in C++
Interview: Critical production skill — detecting leaks with tools, understanding RAII, and demonstrating memory ownership clarity
Memory Leaks
A memory leak occurs when heap-allocated memory is never freed, causing the program's memory consumption to grow over time. In long-running servers and services, even small leaks can accumulate to exhaust all available RAM and crash the process. Memory leaks are one of the most common bugs in C++ and a top interview topic.
Common Leak Patterns
Lost Pointer
Reassigning a pointer without freeing what it pointed to: int* p = new int(1); p = new int(2); — the first int is leaked.
Exception Skip
If an exception is thrown between new and delete, the delete is never reached and the memory leaks.
Cyclic Reference
Two shared_ptrs pointing to each other — reference counts never reach zero even when both go out of scope.
Global / Static Containers
Storing raw pointers in global containers — if the program exits without clearing them, leak detectors report them.
Detection Tools
Valgrind
Full memory error detection on Linux. Slow (10–50×) but comprehensive. Run with --leak-check=full
AddressSanitizer
Compiler instrumentation (-fsanitize=address). 2× overhead, reports leaks, buffer overflows, dangling pointers. Use in CI.
VS Memory Profiler
Built into Visual Studio. Snapshot-based heap analysis for Windows development.
Interview Corner
Q: Why can't the compiler always detect memory leaks?
A: Memory leaks involve runtime behavior — whether a code path is executed and whether a pointer outlives its intended scope. The compiler only sees the static structure. Leak detection requires runtime tracking of every allocation and deallocation, which is what tools like Valgrind and ASan do by intercepting malloc/free at runtime.
Q: How does RAII prevent memory leaks?
A: RAII ties resource lifetime to object lifetime. The destructor is automatically called when a RAII object goes out of scope — even if an exception is thrown. With std::unique_ptr, the owned pointer is deleted in the destructor, making leaks structurally impossible — the resource is freed regardless of how control exits the scope.
Common Pitfalls
- Early return without cleanup: Adding a
returnin the middle of a function that has rawnewd memory. Use RAII to make returns safe. - shared_ptr circular references: Two objects holding shared_ptrs to each other — use
weak_ptrto break cycles.
Best Practices
- Use smart pointers — they make leaks structurally impossible for heap memory.
- Run AddressSanitizer (
-fsanitize=address,leak) in CI to catch leaks in tests before they reach production. - Follow the Rule of Zero/Three/Five for classes that manage resources.