Từ 1 tới 3 trên tổng số 3 kết quả

Đề tài: Cấp phát động và chống memory leak trong lập trình C

  1. #1
    Ngày gia nhập
    07 2008
    Nơi ở
    /media/Anime
    Bài viết
    2,288

    Mặc định Cấp phát động và chống memory leak trong lập trình C

    Bài 1 : Con trỏ và bộ nhớ trong lập trình C for DOS

    Đây là bài thứ 2 trong loạt bài tút của mèo. Tút lần này sẽ nói về cấp phát động trong dos. Nội dung trọng tâm là hướng dẫn cho các bạn hiểu về cách làm việc của cấp phát động và cách víêt chương trình sao cho tiết kiệm bộ nhớ nhất.

    Nhìêu người lầm tưởng là cấp phát động sẽ tạo ra một vùng nhớ mới và nếu giải phóng thì nó huỷ vùng nhớ ấy đi. Cách nói đó chỉ nên hiểu theo nghĩa logic. Trên thực tế là không có vùng nhớ nào bị sinh ra hay mất đi cả, tất cả đều tồn tại trên bộ nhớ của máy tính. Khi cấp phát chẳng qua là ta đăng ký rằng sẽ sử dụng vùng nhớ tại địa chỉ định sẵn và khi giải phóng tức là ta xoá khỏi danh sách đăng ký và vùng nhớ vừa giải phóng sẽ được dùng cho lần cấp phát tiếp theo.

    Qua thực tế phân tích mã máy được biên dịch bời các compiler, mèo rút ra đuợc cách thức làm việc của hàm cấp phát động. Các compiler thường lưu trữ danh sách các vùng nhớ đang sử dụng bằng một cấu trúc gần giống với danh sách liên kết. Đầu tiên là có một vùng header :
    C Code:
    1. typedef struct _memAllocatedHeader
    2. {
    3.     void *base;
    4.     unsigned long size;
    5.     memAllocatedHeader *next, *prev;
    6. } memAllocatedHeader;
    Chú ý là đây chỉ là mã giả để minh hoạ, vùng header trên tuỳ vào compiler sẽ có thêm một số thông tin khác ngoài các thông tin cơ bản trên. Địa chỉ vùng nhớ mà ta nhận được từ các hàm cấp phát động được tính bởi :
    C Code:
    1. address = base + sizeof (memAllocatedHeader);

    Khi tiến hành cấp phát, hàm cấp phát sẽ duyệt đến cuối danh sách này và vùng nhớ dự định cấp phát sẽ có địa chỉ :
    C Code:
    1. address = last->base + last->size;
    Trong đó last là con trỏ đến nút cuối cùng của danh sách.

    Header của vùng nhớ vừa tìm được sẽ được nối vào cuối danh sách, như thế những lần cấp phát sau vùng nhớ này sẽ không đuợc dùng để cấp phát nữa.
    Quá trình giải phóng vùng nhớ chỉ đơn giản là gỡ bỏ nó khỏi danh sách đăng ký vùng nhớ. Vấn đề là làm sao tìm đuợc địa chỉ vùng header để xoá. Ta có thể dễ dàng tính được bằng cách như sau :
    C Code:
    1. memAllocatedHeader *pHeader = (memAllocatedHeader *)((unsigned long)address - sizeof (memAllocatedHeader));
    Và như thế ta chỉ cần tháo gỡ các con trỏ sao cho danh sách vẫn liên tục là xong.

    Phần cuối mình xin trình bày về vấn đề lãng phí bộ nhớ ( memory leak ). Ta dễ thấy rằng, khi quản lý bộ nhớ theo cách trên thì bộ nhớ sẽ bị phân mảnh nhiều hơn và liên tục hơn cả ổ cứng nữa. Ví dụ như chúng ta cấp phát :
    C Code:
    1. char *p1 = new char [1000];
    2. char *p2 = new char [1000];
    3. delete p1;
    4. char *p3 = new char [700];
    5. char *p4 = new char [500];
    Rõ ràng rằng p1 đã được giải phóng và dư ra 1000 byte, tuy nhiên vùng nhớ đó không đủ chứa cho cả p3 và p4. Vùng nhớ của p4 phải đuợc cấp phát phía sau vùng nhớ của p2. Tức là thực tế ta mất 2500 byte để lưu trữ 3 vùng nhớ trên và lãng phí hết 300 byte. Bộ nhớ trong dos khá eo hẹp vì thực sự chương trình chỉ có được 640kb, hơn nữa do các thanh ghi là 16 bit nên chỉ cấp phát tối đa là 65536 byte cho một segment. Đó là con số lý thuyết vì chưa tính đến stack và bíên toàn cục. Trung bình là ta chỉ cấp phát đuợc khoảng 20->30 Kb. Do đó việc cấp phát và huỷ vùng nhớ và chống lãng phí bộ nhớ là điều cần phải chú tâm cao.

    Bài tút đến đây là hết. Cám ơn các bạn đã theo dõi.

    Các bạn nào có thắc mắc gì thì PM mình, mình sẽ mở lại đề tài để các bạn nêu thắc mắc.
    Đã được chỉnh sửa lần cuối bởi meoconlongvang : 06-11-2008 lúc 06:40 PM.
    Càng yêu mèo thì mèo càng mập. Mèo càng mập ta lại càng yêu.

  2. #2
    Ngày gia nhập
    07 2013
    Bài viết
    1

    Bài viết hay quá mà sao không có ai đọc và trả lời nhỉ. Tuy thực sự mình chưa hiểu sâu sắc vấn đề nhưng đây là một bài viết hay vì mình cũng đã đọc một số bài viết khác! Thanks bác rất nhiều!

  3. #3
    Ngày gia nhập
    11 2011
    Bài viết
    2

    Bài viết mới chỉ nêu được một khía cạnh của vấn đề thôi, theo như mình thấy còn rất nhiều trường hợp nữa

Các đề tài tương tự

  1. Kỹ thuật C++ khắc phục memory leak khi cấp phát bộ nhớ cho biến thành phần trong struct
    Gửi bởi KTT trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 6
    Bài viết cuối: 30-06-2012, 04:51 PM
  2. Tính memory leak trong C++ như thế nào?
    Gửi bởi carterku trong diễn đàn Thắc mắc lập trình Visual C++
    Trả lời: 2
    Bài viết cuối: 03-01-2012, 02:40 PM
  3. Memory Leak trong lập trình C#?
    Gửi bởi tamntaptech trong diễn đàn Thắc mắc lập trình C#
    Trả lời: 10
    Bài viết cuối: 16-02-2011, 07:42 AM
  4. memory leak Lỗi này có hay dẫn đến đơ chương trình
    Gửi bởi trần trân trong diễn đàn Thắc mắc lập trình Visual C++
    Trả lời: 1
    Bài viết cuối: 09-12-2009, 10:01 AM
  5. Lập trình C++ | Memory leak với toán tử new
    Gửi bởi learnC trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 2
    Bài viết cuối: 29-05-2009, 01:34 PM

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn