Trong lúc quậy code C, có thể bạn đã gặp một tình huống chương trình dường như "có chút hơi men":
Chương trình chạy ngon
Không crash
Không báo lỗi
👉 Nhưng chạy một lúc thì:
chậm dần
lag dần
rồi… "đứng hình"
Bạn nghĩ:
"Chắc máy yếu…", hoặc là "mạng yếu"
👉 Không. Rất có thể bạn vừa dính memory leak.
Memory leak là gì?
Nói đơn giản:
Memory leak xảy ra khi bạn cấp phát bộ nhớ nhưng quên giải phóng
Trong C:
int *p = malloc(sizeof(int));
👉 Bạn đã "xin" một vùng nhớ từ hệ điều hành
Nhưng nếu bạn không:
free(p);
👉 Vùng nhớ đó sẽ không bao giờ được trả lại
Ví dụ đời thường (rất dễ nhớ)
Bạn đi thuê phòng khách sạn trong kỳ nghỉ Lễ. Sau đó khóa cửa phòng, quay về nhà, đi làm đi học như bình thường.
Nhưng… không bao giờ trả phòng khách sạn.
👉 Một mình bạn chiếm 1 phòng → không sao
👉 1000 người như vậy → hết phòng → "toang"
Ví dụ code kinh điển
#include <stdlib.h>
int main() {
while (1) {
int *p = malloc(sizeof(int));
}
}
Chương trình chạy ngon
Không crash
Không báo lỗi
👉 Nhưng chạy một lúc thì:
chậm dần
lag dần
rồi… "đứng hình"
Bạn nghĩ:
"Chắc máy yếu…", hoặc là "mạng yếu"
👉 Không. Rất có thể bạn vừa dính memory leak.
Memory leak là gì?
Nói đơn giản:
Memory leak xảy ra khi bạn cấp phát bộ nhớ nhưng quên giải phóng
Trong C:
int *p = malloc(sizeof(int));
👉 Bạn đã "xin" một vùng nhớ từ hệ điều hành
Nhưng nếu bạn không:
free(p);
👉 Vùng nhớ đó sẽ không bao giờ được trả lại
Ví dụ đời thường (rất dễ nhớ)
Bạn đi thuê phòng khách sạn trong kỳ nghỉ Lễ. Sau đó khóa cửa phòng, quay về nhà, đi làm đi học như bình thường.
Nhưng… không bao giờ trả phòng khách sạn.
👉 Một mình bạn chiếm 1 phòng → không sao
👉 1000 người như vậy → hết phòng → "toang"
Ví dụ code kinh điển
#include <stdlib.h>
int main() {
while (1) {
int *p = malloc(sizeof(int));
}
}
👉 Mỗi vòng lặp:
xin thêm 1 vùng nhớ
nhưng không trả
👉 Kết quả:
RAM tăng dần
rồi… 💀
Vì sao memory leak nguy hiểm?
Khác với segmentation fault:
❌ Segfault → crash ngay (còn biết đường sửa)
❌ Memory leak → không crash ngay. Cứ tưởng là mọi thứ ổn!
👉 Nó âm thầm:
ăn RAM
làm chương trình chậm
lâu dài → sập
Kiểu như sóng biển vỗ bờ, âm thầm xâm lấn vậy...
5 nguyên nhân phổ biến gây memory leak
❌ 1. Quên free
int *p = malloc(sizeof(int));
// quên free
👉 Đây là "classic"
❌ 2. Ghi đè pointer
int *p = malloc(sizeof(int));
p = malloc(sizeof(int)); // leak vùng nhớ cũ
👉 Bạn mất luôn địa chỉ vùng nhớ đầu tiên → không free được nữa
❌ 3. Return sớm (quên dọn dẹp)
int *p = malloc(sizeof(int));
if (error) return; // leak
👉 Chưa kịp free đã "bỏ chạy"
❌ 4. Cấu trúc phức tạp (struct, linked list…)
👉 Khi dùng:
list
tree
👉 Rất dễ:
free thiếu
free sai
❌ 5. Lặp nhiều lần (loop)
👉 Code tưởng đúng:
while (1) {
char *buf = malloc(100);
}
👉 Nhưng:
chạy lâu → chết chắc
Để hiểu rõ hơn, mục sở thị kết quả bằng xương bằng thịt, chúng ta sẽ cần thực hành một chút.
Bạn copy code sau vào:
👉 Online C Compiler
#include <stdlib.h>
#include <stdio.h>
int main() {
int count = 0;
while (1) {
malloc(1000); // leak
count++;
if (count % 10000 == 0) {
printf("Allocated %d blocks\n", count);
}
}
return 0;
}
Bấm Run chạy thử
👉 Bạn sẽ thấy:
chương trình chạy
nhưng RAM tăng dần
Cách phát hiện memory leak
✅ Cách 1: Quan sát RAM
Task Manager / top / htop
👉 thấy RAM tăng liên tục → nghi ngay
✅ Cách 2: Dùng tool chuyên dụng
Ví dụ:
Valgrind (Linux)
valgrind ./program
👉 Nó sẽ báo:
chỗ nào leak
leak bao nhiêu
✅ Cách 3: Tự discipline (Tự mò mẫm)
👉 Rule đơn giản:
malloc ở đâu → free ở đó (hoặc có kế hoạch rõ ràng)
Cách tránh memory leak (rất thực tế)
✅ 1. malloc → luôn nghĩ đến free
👉 Viết code mà không nghĩ đến free là… sớm muộn gì cũng leak
✅ 2. Set NULL sau khi free
free(p);
p = NULL;
👉 Tránh dùng lại nhầm
✅ 3. Không ghi đè pointer
👉 Nếu cần:
free(p);
p = malloc(sizeof(int));
✅ 4. Với project lớn → viết rule rõ ràng
Ai cấp phát?
Ai giải phóng?
👉 Không rõ = leak
Một sự thật hơi "đau"
👉 Rất nhiều phần mềm ngoài đời:
không crash
nhưng chạy lâu → chậm
👉 Lý do: memory leak
Tổng kết
Memory leak không làm chương trình crash ngay
👉 Nhưng nó "ăn dần" tài nguyên
Chỉ cần nhớ:
malloc → phải free
Không free → leak
Leak nhiều → chết
❓ Memory leak có gây segmentation fault không?
→ Không trực tiếp, nhưng có thể gián tiếp khi hết memory
❓ Có thể tránh hoàn toàn memory leak không?
→ Rất khó, nhưng có thể giảm rất nhiều nếu quản lý tốt
❓ Ngôn ngữ khác có memory leak không?
→ Có, nhưng ít hơn (do có garbage collector)
👉 Bạn có thể cũng đang gặp:
Segmentation fault trong C là gì?
Con trỏ NULL nguy hiểm ra sao?
Stack vs Heap khác nhau thế nào?
(👉 sẽ có trong các bài tiếp theo)
Không có nhận xét nào:
Đăng nhận xét