Giao diện
❌ new/delete — The Dangerous Way
new và delete là cách thủ công để cấp phát bộ nhớ. Chúng nguy hiểm và nên tránh trong Modern C++. Analogy: Mượn tiền không trả
┌─────────────────────────────────────────────────────────────────┐
│ BORROWING MONEY ANALOGY │
├─────────────────────────────────────────────────────────────────┤
│ │
│ new = Mượn tiền từ ngân hàng (Heap) │
│ delete = Trả tiền lại │
│ │
│ 😰 MEMORY LEAK = Mượn xong quên trả │
│ → Ngân hàng hết tiền cho vay (RAM hết) │
│ │
│ 😱 DOUBLE FREE = Trả 2 lần cùng 1 khoản │
│ → Ngân hàng confused, database corrupted │
│ │
│ 💀 DANGLING POINTER = Cầm receipt của khoản đã trả │
│ → Dùng receipt cũ = undefined behavior │
│ │
└─────────────────────────────────────────────────────────────────┘Basic new/delete
cpp
// Allocate single object
int* ptr = new int; // Allocate
*ptr = 42; // Use
delete ptr; // Free
// Allocate array
int* arr = new int[100]; // Allocate 100 ints
arr[0] = 1; // Use
delete[] arr; // Free array (note the [])The Problems
1. Memory Leak
cpp
void memoryLeak() {
int* ptr = new int(42);
// Oops! Forgot to delete
// ptr goes out of scope, memory is LOST forever
}
// Each call leaks 4 bytes
// Call 1 million times = 4MB leaked!2. Leak on Exception
cpp
void leakOnException() {
int* ptr = new int(42);
doSomething(); // If this throws exception...
delete ptr; // This line NEVER executes!
}3. Double Free
cpp
void doubleFree() {
int* ptr = new int(42);
delete ptr;
// ... later, forgot we deleted ...
delete ptr; // 💥 UNDEFINED BEHAVIOR!
}4. Dangling Pointer
cpp
int* danglingPointer() {
int* ptr = new int(42);
int* copy = ptr;
delete ptr;
// copy still points to freed memory!
return copy; // 💀 Returning garbage
}
void useDangling() {
int* bad = danglingPointer();
*bad = 10; // 💥 Writing to freed memory!
}Error Examples
cpp
// ❌ Memory leak - forgot delete
void bad1() {
int* p = new int[1000];
// return without delete
}
// ❌ Wrong delete type
void bad2() {
int* arr = new int[100];
delete arr; // Should be delete[]!
}
// ❌ Delete stack memory
void bad3() {
int x = 10;
int* p = &x;
delete p; // 💥 x is on STACK, not heap!
}
// ❌ Use after delete
void bad4() {
int* p = new int(42);
delete p;
std::cout << *p; // 💥 Undefined behavior!
}Trying to Fix It (Still Bad)
cpp
void tryingToBeCareful() {
int* ptr = new int(42);
try {
doRiskyOperation();
delete ptr;
} catch (...) {
delete ptr; // Duplicate code!
throw;
}
}Vấn đề: Phải nhớ delete ở MỌI đường code path!
Statistics
┌─────────────────────────────────────────────────────────────────┐
│ MEMORY BUG STATISTICS │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 📊 Microsoft: 70% of CVEs are memory safety issues │
│ 📊 Chrome: 70% of serious security bugs are memory bugs │
│ 📊 Firefox: Similar statistics │
│ │
│ Most common: │
│ • Use-after-free │
│ • Buffer overflow │
│ • Uninitialized memory │
│ │
│ 💡 Solution: Don't use raw new/delete! │
│ │
└─────────────────────────────────────────────────────────────────┘When is new/delete OK?
⚠️ RARE CASES
Chỉ dùng new/delete trực tiếp khi:
- Implementing custom containers/allocators
- Interfacing with C libraries
- Extreme performance optimization
Cho 99% code, KHÔNG BAO GIỜ dùng raw new/delete!
📚 Tổng kết
| Problem | Description |
|---|---|
| Memory Leak | Quên delete → RAM exhausted |
| Double Free | Delete 2 lần → Corruption |
| Dangling Pointer | Dùng sau khi delete → UB |
| Exception Unsafe | Exception = leak |
➡️ Tiếp theo
Giải pháp cho tất cả vấn đề trên: RAII
RAII → — The heart of C++.