🌱 Memory Leak và Ví dụ
Khi phát triển phần mềm, lập trình viên gặp rất nhiều khó khăn, đặc biệt với những "bug kỳ lạ" - Kỳ lạ một phần do chẳng biết nó đến từ đâu cả 😅 Đặc biệt với anh em làm phần mềm nhúng, thì mất cái kỳ lạ này còn thường xuyên xảy ra hơn:
- Code vừa chạy ngon xong nhưng mà chạy lại thì báo lỗi.
- Run thì báo lỗi tùm lum nhưng debug từng bước thì lại đúng.
- Treo mạch 😑
👉 Các vấn đề thường gặp khi thiết kế phần mềm nhúng
- Vấn đề về quản lý tài nguyên (chân cẳng, bộ nhớ),
- Vấn đề quản lý các ngắt - thiết kế luồng quản lý chương trình hợp lý,
- Vấn đề lập lịch - quản lý task trong hệ điều hành,
- Vấn đề thiết kế chương trình.
👉 Memory Leak là gì?
Trong khoa học máy tính, Memory Leak - Rò rỉ bộ nhớ là một dạng rò rỉ tài nguyên xảy ra khi chương trình máy tính quản lý không chính xác việc cấp phát bộ nhớ theo cách bộ nhớ không cần dùng nữa, mà lại không được giải phóng.
Anh em lập trình C nghe có thể nghĩ ngay đến trường hợp dùng malloc() nhưng không free() đúng không? Trên thực tế thì có rất nhiều trường hợp có thể gây ra Memory Leak:
- Thiếu bộ nhớ RAM (Stack Overflow, Heap Overflow, ...),
- Đọc/Ghi tràn mảng, khi đọc ghi quá số phần tử max của mảng cũng có thể gây ra các vấn đề về bộ nhớ. Tuy nhiên, một số Compiler đã hỗ trợ báo build fail để cảnh báo cho người lập trình.
- Tràn biến, chia cho 0, ...
- Và cái lỗi thường gặp, malloc() nhưng quên free(). Một khi đã malloc() thì anh em thường rất "tham lam" dùng toàn mảng với truct (Đối với bộ nhớ nhỏ của Vi điều khiển thì chỗ này chiếm khá nhiều). Mà một khi dùng xong quên free thì không khác gì đặt thêm mấy cái quả tạ trăm cân ở giữa nhà bếp !!!
👉 Một số ví dụ về Memory Leak
💬 Ví dụ 1
#include <stdlib.h>
#include <stdio.h>
#define LOOPS 10
#define MAXSIZE 256
int main(int argc, char **argv)
{
int count = 0;
char *pointer = NULL;
for(count=0; count<LOOPS; count++)
{
pointer = (char *)malloc(sizeof(char) * MAXSIZE);
}
free(pointer);
return count;
}
Vì vậy, các block được cấp phát ban đầu sẽ không có pointer trỏ vào, và không thể free chúng được ⇨ Tiêu tốn cực nhiều bộ nhớ.
Kiểu này thường gặp nhưng cũng dễ để xử lý, bằng cách đưa hàm free() vào trong vòng lặp for.
💬 Ví dụ 2
char* getBlock(int fd)
{
char* buf = (char*) malloc(BLOCK_SIZE);
if (!buf)
{
return NULL;
}
if (read(fd, buf, BLOCK_SIZE) != BLOCK_SIZE)
{
return NULL;
}
return buf;
}
Trên đây là một ví dụ đơn giản khác về Memory Leak. Hàm trên sẽ đọc một block nhớ mong muốn, nếu đọc được sẽ free vùng nhớ được phân bổ trong hàm.
Tuy nhiên, nếu hàm read() trả về sai số bytes mong muốn (BLOCK_SIZE) thì hàm sẽ trả về NULL, từ đó block nhớ đã malloc() trong hàm sẽ không được free() và gây ra Memory Leak.
Ngoài ra còn rất nhiều ví dụ khác về Memory Leak mà các bạn có thể tham khảo hoặc đã từng gặp phải 😆
>>>= Follow ngay =<<<
💚 Kênh Youtube Lập trình - Điện tử 💚
Để nhận được những bài học miễn phí mới nhất nhé 😊
Chúc các bạn học tập tốt 😊
0 Nhận xét