[2026] C++ Heap Corruption: Double Free, Wrong delete[], and Detection
이 글의 핵심
Heap corruption in C++: buffer overruns, double delete, delete vs delete[], use-after-free, ASan and Valgrind, and RAII patterns to stay safe.
What is heap corruption?
Damage to heap bookkeeping or adjacent memory, often from out-of-bounds writes or invalid free/delete.
int* arr = new int[10];
arr[10] = 42; // out of bounds
delete[] arr;
Common causes
아래 코드는 cpp를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
int* arr = new int[10];
arr[15] = 42;
int* ptr = new int(10);
delete ptr;
delete ptr;
int* arr = new int[10];
delete arr; // should be delete[]
int* ptr = new int(10);
delete ptr;
*ptr = 42;
Examples
Example 1: Buffer overflow on the heap
다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
#include <iostream>
#include <cstring>
void bufferOverflow() {
char* buffer = new char[10];
strcpy(buffer, "This is too long");
delete[] buffer;
}
void safeBuffer() {
char* buffer = new char[20];
strncpy(buffer, "This is safe", 19);
buffer[19] = '\0';
delete[] buffer;
}
void useString() {
std::string str = "This is safe";
}
Example 2: Double free
다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
#include <memory>
void doubleFree() {
int* ptr = new int(10);
delete ptr;
delete ptr;
}
void safeFree() {
int* ptr = new int(10);
delete ptr;
ptr = nullptr;
delete ptr;
}
void smartPointer() {
auto ptr = std::make_unique<int>(10);
}
Example 3: Wrong delete
다음은 cpp를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
void wrongDelete() {
int* arr = new int[10];
delete arr;
}
void correctDelete() {
int* arr = new int[10];
delete[] arr;
int* ptr = new int(10);
delete ptr;
}
void smartPointer() {
auto arr = std::make_unique<int[]>(10);
auto ptr = std::make_unique<int>(10);
}
Example 4: Use-after-free
다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
#include <iostream>
void useAfterFree() {
int* ptr = new int(10);
delete ptr;
std::cout << *ptr << std::endl;
}
void safeUse() {
int* ptr = new int(10);
std::cout << *ptr << std::endl;
delete ptr;
}
void smartPointer() {
auto ptr = std::make_unique<int>(10);
std::cout << *ptr << std::endl;
}
Detection
// ASan: g++ -fsanitize=address -g program.cpp
// Valgrind: valgrind --tool=memcheck ./program
Common pitfalls
Pitfall 1: Off-by-one loops
아래 코드는 cpp를 사용한 구현 예제입니다. 반복문으로 데이터를 처리합니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
int* arr = new int[10];
for (int i = 0; i < 10; i++) {
arr[i] = i;
}
delete[] arr;
std::vector<int> vec(10);
Pitfall 2: Mixing new and realloc
std::vector<int> vec(10);
vec.resize(20);
Pitfall 3: Pointer arithmetic out of range
아래 코드는 cpp를 사용한 구현 예제입니다. 조건문으로 분기 처리를 수행합니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
int* arr = new int[10];
if (index < 10) {
arr[index] = 42;
}
delete[] arr;
Pitfall 4: Struct members not freed
아래 코드는 cpp를 사용한 구현 예제입니다. 클래스를 정의하여 데이터와 기능을 캡슐화하며. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
struct Node {
int* data;
Node* next;
};
void deleteNode(Node* node) {
delete[] node->data;
delete node;
}
struct NodeSafe {
std::unique_ptr<int[]> data;
std::unique_ptr<NodeSafe> next;
};
Prevention
auto ptr = std::make_unique<int>(10);
auto arr = std::make_unique<int[]>(10);
std::vector<int> vec(10);
Debugging tools
g++ -fsanitize=address -g program.cpp
./a.out
valgrind --leak-check=full --show-leak-kinds=all ./program
FAQ
Q1: When does heap corruption happen?
A: Overflows, double free, wrong delete form, UAF.
Q2: Detection?
A: ASan, Valgrind, debug heap (platform-specific).
Q3: Prevention?
A: Smart pointers, containers, RAII.
Q4: Symptoms?
A: Crashes, flaky behavior, corruption far from the bug.
Q5: delete vs delete[]?
A: delete for single object; delete[] for new[] arrays.
Q6: Resources?
A: Effective C++, ASan docs, Valgrind docs.
See also
Practical tips
Debugging
- Warnings first
- Small repro
Performance
- Profile first
Code review
- Conventions
Checklist
Before coding
- Right approach?
- Maintainable?
- Performance?
While coding
- Warnings?
- Edge cases?
- Errors?
At review
- Clear?
- Tests?
- Docs?