2013-05-03 29 views
6

chúng tôi phân bổ bộ nhớ động trong C bằng cách sử dụng malloc() và chúng tôi nhận được một con trỏ đến một vị trí trong heap. bây giờ chúng tôi sử dụng miễn phí() để deallocate bộ nhớ, đi qua cùng một giá trị con trỏ như argumnet của nó.Làm thế nào được cấp phát bộ nhớ động theo dõi trong C

Câu hỏi bây giờ là cách miễn phí() biết bao nhiêu để deallocate .. xem xét thực tế là chúng tôi luôn có thể thay đổi kích thước khối bộ nhớ được phân bổ bởi malloc().

có điều gì liên quan đến Bảng băm ở đây không?

Trả lời

4

Kỹ thuật ban đầu là phân bổ một khối lớn hơn một chút và lưu trữ kích thước ngay từ đầu, một phần mà ứng dụng không nhìn thấy. Không gian thừa chứa kích thước và có thể liên kết tới chuỗi các khối miễn phí với nhau để sử dụng lại.

Có một số vấn đề nhất định với các thủ thuật đó, chẳng hạn như hành vi quản lý bộ nhớ cache và bộ nhớ kém. Việc sử dụng bộ nhớ ngay trong khối có xu hướng sắp xếp mọi thứ một cách không cần thiết và cũng tạo ra các trang bẩn làm phức tạp việc chia sẻ và sao chép trên ghi.

Vì vậy, kỹ thuật nâng cao hơn là giữ một thư mục riêng biệt. Các phương pháp tiếp cận kỳ lạ cũng đã được phát triển trong đó các khu vực bộ nhớ sử dụng cùng một kích cỡ hai chiều.

Nói chung, câu trả lời là: cấu trúc dữ liệu riêng biệt được phân bổ để giữ trạng thái.

+3

Lưu trữ kích thước ở cuối sẽ là một chiến lược không hiệu quả vô vọng. Và tôi không nghĩ về http://en.wikipedia.org/wiki/Buddy_memory_allocation là "kỳ lạ". –

+0

Err, heh, tôi đang cố gắng nói điều gì đó hơi khác. Đã sửa! – DigitalRoss

+0

Tôi đã thấy kỹ thuật tương tự trong nhân Linux với phân bổ bộ nhớ hạt nhân bằng cách sử dụng "struct page" được lưu trữ ở đầu vùng bộ nhớ được cấp phát và cấu trúc được sử dụng để giữ trạng thái bộ nhớ. – ArunMKumar

5

Việc triển khai điển hình sẽ lưu trữ thông tin ngay trước địa chỉ được trả về bởi malloc. Thông tin đó sẽ bao gồm thông tin mà realloc hoặc nhu cầu miễn phí cần biết để thực hiện công việc của họ, nhưng chi tiết về chính xác những gì được lưu trữ ở đó phụ thuộc vào việc triển khai.

1

Trình quản lý bộ nhớ sử dụng bảng để lưu trữ dữ liệu bổ sung dựa trên con trỏ, đôi khi ngay trước con trỏ, đôi khi ở nơi khác. Với C rất đơn giản, dữ liệu rất có thể là pointer-2 hoặc pointer-4, dưới dạng int hoặc long loại. Các chi tiết chính xác phụ thuộc vào trình biên dịch.

+2

Các chi tiết phụ thuộc vào thư viện C, là một phần của việc thực hiện ngôn ngữ. Trình biên dịch không có gì để làm với nó. Ngoài ra, một số triển khai giữ các khối có kích thước nhỏ trong các vùng bộ nhớ được xác định bởi địa chỉ của bộ nhớ, do đó kích thước không được giữ ở bất kỳ đâu cho các khối như vậy. –

+0

Rất tiếc, thực tế kích thước được giữ ở đâu đó (và phải) ... nó được lưu giữ trong cấu trúc dữ liệu mô tả nhóm bộ nhớ. –

1

Khi chúng tôi sử dụng malloc, một khối sẽ nhận được dự trữ có kích thước sẽ nhỏ hơn nhiều so với những gì chúng tôi đã yêu cầu và để trở lại malloc này, chúng tôi nhận được một con trỏ để bắt đầu khối này. AS tôi đã nói với bạn kích thước của khối này sẽ được littile nhiều hơn những gì chính xác bạn cần. Không gian thêm này sẽ được sử dụng để giữ kích thước yêu cầu thực tế của khối, con trỏ đến khối miễn phí tiếp theo và một số dữ liệu kiểm tra "nếu bạn cố gắng truy cập nhiều hơn hơn khối được phân bổ ". Vì vậy, bất cứ khi nào chúng tôi gọi miễn phí bằng cách sử dụng con trỏ chúng tôi muốn deallocate, miễn phí này sẽ tìm kiếm thêm thông tin được đưa ra trong không gian khối, Nơi nó được kích thước cuối cùng để deallocate.

2

Một thực hiện simplist là một trong những nổi tiếng K&R C Bible, trang 186 - 188.

Khối bộ nhớ chúng ta có thực sự là hơn (một đầu struct hoặc kích thước một đầu đoàn của) so với chúng tôi áp dụng cho.Các struct có thể như thế này:

typedef long Align; 

union header 
{ 
    struct 
    { 
     union header* ptr; // next block 
     unsigned size;  // size of this block , times of head size 
    }s; 
    Align x; 
}; 

Một con số để chứng minh điều đó:

enter image description here

Khi chúng ta gọi là free chức năng, hành vi có thể là như thế này:

void free(void* ptr) 
{ 
    Header *bp, *p; 

    bp = (Header *)ptr - 1; 

    /* .....    */ 
    /*return the memory to the linked list */ 
} 

Trong phòng thu trực quan, chúng tôi có hai mô hình: release versiondebug version, chúng tôi thậm chí có thể sử dụng người đứng đầu để nhắn lưu trữ debug để gỡ lỗi easier.The tiêu đề trong debug version được gọi _CrtMemBlockHeader, định nghĩa như sau:

typedef struct _CrtMemBlockHeader 
{ 
    struct _CrtMemBlockHeader * pBlockHeaderNext; 
    struct _CrtMemBlockHeader * pBlockHeaderPrev; 
    char *      szFileName; 
    int       nLine; 
    size_t      nDataSize; 
    int       nBlockUse; 
    long      lRequest; 
    unsigned char    gap[nNoMansLandSize]; 
} _CrtMemBlockHeader; 

Sau đó lalout bộ nhớ là:

enter image description here

+0

Cảm ơn rất nhiều vì đã đưa ra điều đó .. tôi đã có kinh thánh và bỏ lỡ chủ đề đó hoàn toàn. Mô tả của bạn làm cho cảm giác hoàn thành – ArunMKumar

+0

Vui mừng khi đến đây. – prehistoricpenguin

Các vấn đề liên quan