How to Diagnose C++ Memory Leaks and Segmentation Faults for High‑Frequency Interviews
The article explains why memory leaks and segmentation faults are hard‑to‑detect hidden bugs in Linux C++ back‑end and embedded development, illustrates common causes with concrete code samples, and walks through Linux commands and tools such as top, ps, pmap, vmstat, Valgrind, AddressSanitizer, memleak and gdb to locate and fix these issues.
In Linux C++ back‑end and embedded development, memory leaks and segmentation faults are the most hidden runtime errors, often appearing only after long‑running, high‑concurrency workloads.
Typical memory errors
1. Memory not released (leak)
#include <stdio.h>
#include <stdlib.h>
void memory_leak_example() {
int *ptr = (int *)malloc(sizeof(int));
// missing free(ptr)
}
int main() {
for (int i = 0; i < 1000; i++) {
memory_leak_example();
}
return 0;
}The loop allocates an int on each iteration without freeing it, causing the resident set size (RSS) to grow until the process is OOM‑killed.
2. Wild pointer access
#include <iostream>
void wild_pointer_example() {
int *ptr; // uninitialized
std::cout << *ptr << std::endl; // undefined behavior
int *ptr2 = new int(10);
delete ptr2;
std::cout << *ptr2 << std::endl; // use‑after‑free
}
int main() {
wild_pointer_example();
return 0;
}Dereferencing an uninitialized pointer and a pointer after delete both produce undefined behavior that can crash the program.
3. Double free
#include <iostream>
void double_free_example() {
int *ptr = new int(10);
delete ptr;
delete ptr; // double free, undefined behavior
}
int main() {
double_free_example();
return 0;
}Calling delete twice corrupts the allocator’s metadata and may lead to crashes or security issues.
4. Buffer overflow
#include <stdio.h>
#include <string.h>
void buffer_overflow_example() {
char buffer[5];
char *str = "Hello, World!";
strcpy(buffer, str); // overflow
printf("%s
", buffer);
}
int main() {
buffer_overflow_example();
return 0;
}Copying a longer string into a 5‑byte array overwrites adjacent memory, which can cause crashes or be exploited.
Locating anomalies at runtime
top – real‑time view of per‑process RES and %MEM; sort by memory usage.
ps aux – shows VSZ, RSS and %MEM for all processes; combine with grep to filter.
pmap <pid> – detailed memory map of a process, useful for spotting unusually large anonymous regions.
vmstat – system‑wide memory statistics; a steady decline of free and rise of swap often indicates a leak.
Deep analysis tools
Valgrind – install via package manager (e.g., sudo apt-get install valgrind). Run with valgrind --leak-check=full ./test; add --track-origins=yes to trace uninitialized reads. Sample output:
==12345== 1024 bytes in 1 blocks are definitely lost in loss record 1 of 1
==12345== at 0x483B7F3: malloc (vg_replace_malloc.c:309)
==12345== by 0x4012A6: process_order (order.c:15)
==12345== by 0x4015C3: main (main.c:42)AddressSanitizer (ASan) – compile with -fsanitize=address -g -O0 (or add the flags in CMakeLists.txt). Example compile command:
g++ -fsanitize=address -g -O0 main.cpp -o mainWhen a violation occurs, ASan aborts and prints a report, e.g.:
==12345==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000ef84 READ of size 4
#0 0x4dd123 in process_array(int*) /path/to/main.cpp:15
#1 0x4dd2a7 in main /path/to/main.cpp:25memleak – eBPF‑based tracer. Typical usage:
sudo memleak -p <pid> -o | tee memory_leak.logOr continuous monitoring:
watch -n 10 sudo memleak -p -c 20Sample output shows top allocation stacks:
[12:34:56] Top 10 stacks with outstanding allocations:
128 bytes in 4 allocations from stack malloc+0x1a [libc] create_object+0x25 [myapp] process_request+0x67 [myapp]
512 bytes in 2 allocations from stack calloc+0x15 [libc] init_buffer+0x3e [myapp]Analyzing a crash stack
Compile with -g to embed debug symbols.
Run gdb <executable>, then bt to print the backtrace. Example backtrace:
#0 0x0000000000401234 in function_c () at file_c.c:50
#1 0x0000000000401567 in function_b () at file_b.c:30
#2 0x000000000040189a in function_a () at file_a.c:15
#3 0x0000000000401abc in main () at main.c:10If a core dump exists, use gdb -c core_dump_file <executable> to inspect the state at the moment of failure.
Understanding the backtrace lets you pinpoint the exact source line that caused the fault (e.g., an out‑of‑bounds array access) and correct the code.
Key takeaways
Memory leaks are forgotten heap allocations; segmentation faults are illegal virtual‑memory accesses. A combined workflow of system commands, Valgrind, AddressSanitizer and gdb can locate virtually all Linux C++ memory anomalies, enabling stable, high‑performance code.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Deepin Linux
Research areas: Windows & Linux platforms, C/C++ backend development, embedded systems and Linux kernel, etc.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
