Title Image

Blog Logo

Memory Leak và Ví dụ

🌱 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

    Ờ, kể ra thì nhiều lắm, có rất nhiều vấn đề xung quanh các lỗi này, vì vậy, mình chỉ nếu ra một số vấn đề tiêu biểu để anh em cùng bàn luận: 
  • 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. 
    Bài viết này mình sẽ nói về một vấn đề trong quản lý tài nguyên, mà cụ thể là bộ nhớ, đó là Memory Leak
    Có thể nói đây là một vấn đề rất đặc trưng của Embedded Software so với những anh em Software khác, vì lúc họ nói về RAM 8G, bộ nhớ trong 512GB thì chúng ta lại lủi thủi với những bo mạch 4GB bộ nhớ (là loại siêu nhiều 😆). Chính vì vậy, việc thường xuyên phải đối mặt với những vấn đề về bộ nhớ, việc chuẩn bị những cách xử lý trước khi nó xảy là điều mà anh em Embedded Sofware Developer cần phải chuẩn bị trước. 

    👉 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. 

Memory Leak

    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;
}

    Trong ví dụ này, chúng ta được cấp phát 10 block ô nhớ với kích thước là MAXSIZE = 256 để có thể làm những công việc khác nhau. Với một vòng for như trên thì pointer sẽ chỉ trỏ được vào block cuối cùng. 

    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 😊 

Đăng nhận xét

0 Nhận xét