Đó thực sự là một câu hỏi khá mơ hồ, và đó có thể là lý do tại sao bạn bị lẫn lộn. Ông có nghĩa là, cho một thực hiện malloc hiện có, làm thế nào bạn sẽ đi về cố gắng để phát triển một cách hiệu quả hơn để giải phóng bộ nhớ cơ bản? Hay anh ta mong bạn bắt đầu thảo luận về các loại triển khai malloc khác nhau và lợi ích và vấn đề của họ? Anh ta có mong đợi bạn biết các chức năng bộ nhớ ảo trên kiến trúc x86 không?
Ngoài ra, hiệu quả hơn, anh ấy có nghĩa là có nhiều không gian hiệu quả hơn hoặc tiết kiệm thời gian hơn không? Liệu miễn phí() phải được xác định? Liệu nó có phải trả lại bộ nhớ cho hệ điều hành càng nhiều càng tốt vì nó ở trong một môi trường bộ nhớ thấp, đa tác vụ? Tiêu chí của chúng tôi ở đây là gì?
Thật khó để nói bắt đầu từ đâu với một câu hỏi mơ hồ như thế, ngoài việc bắt đầu đặt câu hỏi của riêng bạn để làm rõ. Sau khi tất cả, để thiết kế chức năng miễn phí của riêng bạn, trước tiên bạn phải biết làm thế nào malloc được thực hiện. Vì vậy, rất có thể là, câu hỏi thực sự là về việc liệu bạn có biết bất cứ điều gì về việc làm thế nào malloc có thể được thực hiện.
Nếu bạn không quen thuộc với nội bộ của quản lý bộ nhớ, cách dễ nhất để bắt đầu với sự hiểu biết cách triển khai malloc là trước tiên hãy viết của riêng bạn.
Khám phá this IBM DeveloperWorks article called "Inside Memory Management" để bắt đầu.
Nhưng trước khi bạn có thể viết malloc của riêng bạn/miễn phí, trước tiên bạn cần bộ nhớ để phân bổ/miễn phí. Thật không may, trong một hệ điều hành chế độ bảo vệ, bạn không thể trực tiếp địa chỉ bộ nhớ trên máy. Vậy làm thế nào để bạn có được nó?
Bạn yêu cầu hệ điều hành. Với các tính năng bộ nhớ ảo của x86, bất kỳ bộ nhớ RAM hoặc bộ nhớ hoán đổi nào cũng có thể được ánh xạ tới địa chỉ bộ nhớ của hệ điều hành. Những gì chương trình của bạn nhìn thấy như bộ nhớ có thể được phân mảnh vật lý trong suốt toàn bộ hệ thống, nhưng nhờ trình quản lý bộ nhớ ảo của hạt nhân, tất cả đều giống nhau.
Nhân thường cung cấp các cuộc gọi hệ thống cho phép bạn ánh xạ trong bộ nhớ bổ sung cho quy trình của bạn. Trên hệ điều hành UNIX cũ, điều này thường là brk/sbrk để phát triển bộ nhớ heap lên cạnh của quá trình của bạn hoặc thu nhỏ nó, nhưng rất nhiều hệ thống cũng cung cấp mmap/munmap để ánh xạ một khối lớn bộ nhớ heap. có quyền truy cập vào một khối bộ nhớ lớn, liền kề nhìn mà bạn cần malloc/miễn phí để quản lý nó.
Khi quá trình của bạn có một số bộ nhớ heap sẵn có, tất cả đều chia nhỏ thành từng phần, với mỗi đoạn chứa thông tin meta của chính nó về kích thước và vị trí của nó và có phân bổ hay không. Một danh sách các cấu trúc đơn giản, mỗi trường chứa một số thông tin meta và một mảng lớn các byte, có thể hoạt động, trong trường hợp malloc phải chạy qua danh sách cho đến khi tìm thấy một đoạn lớn chưa được phân bổ (hoặc các khối có thể kết hợp), và sau đó bản đồ trong bộ nhớ nhiều hơn nếu nó không thể tìm thấy một đoạn đủ lớn. Một khi bạn tìm thấy một đoạn, bạn chỉ cần trả về một con trỏ đến dữ liệu. free() sau đó có thể sử dụng con trỏ đó để đảo ngược một vài byte vào các trường thành viên tồn tại trong cấu trúc, sau đó nó có thể sửa đổi (tức là đánh dấu chunk.allocated = false;).Nếu có đủ các phần chưa được phân bổ ở cuối danh sách của bạn, bạn thậm chí có thể xóa chúng khỏi danh sách và unmap hoặc thu hẹp bộ nhớ đó khỏi đống quá trình của bạn.
Đó thực sự là một phương pháp đơn giản để triển khai malloc. Như bạn có thể tưởng tượng, có rất nhiều cách có thể tách bộ nhớ của bạn thành nhiều phần và sau đó quản lý các khối đó. Có nhiều cách như có cấu trúc dữ liệu và thuật toán. Tất cả chúng đều được thiết kế cho các mục đích khác nhau, như hạn chế phân mảnh do các khối nhỏ, được phân bổ trộn với các khối nhỏ, chưa được phân bổ, hoặc đảm bảo rằng malloc và tự do chạy nhanh (hoặc đôi khi thậm chí chậm hơn, nhưng dự đoán chậm). Có dlmalloc, ptmalloc, jemalloc, Hoard's malloc và nhiều thứ khác ngoài đó và nhiều thứ trong số đó khá nhỏ và gọn gàng, vì vậy đừng ngại đọc chúng. Nếu tôi nhớ chính xác, "Ngôn ngữ lập trình C" của Kernighan và Ritchie thậm chí còn sử dụng triển khai thực hiện malloc đơn giản như một ví dụ của họ.
Bạn sẽ cần 'malloc' của riêng mình để điều này hữu ích, đúng không? – pmr
Vì việc thực hiện 'miễn phí' không được chỉ định bởi tiêu chuẩn, tôi không thấy làm thế nào mà bất cứ ai có thể trả lời 2. –
Bạn không thể đưa ra câu trả lời tuyệt đối, nhưng nó tạo ra một điểm nói tốt - có lẽ là điểm! Tôi đồng ý bạn cần malloc của riêng bạn nếu không không có phạm vi để tái sử dụng bộ nhớ. Thật vậy, chỉ ra những điều "rõ ràng" đó có lẽ là những gì anh ta/cô ấy theo sau bởi một cuộc thảo luận chuyên sâu hơn về cách viết một hệ thống phân bổ bộ nhớ động hiệu quả (tốc độ so với bộ nhớ vv). Hãy nhớ rằng: một người phỏng vấn không cố lừa bạn, nhưng đang cố gắng xem bạn giải quyết vấn đề như thế nào và bạn biết gì. Suy nghĩ to và yêu cầu làm rõ. Cho họ thấy những gì bạn biết! – noelicus