Điều này đã là một cái gì đó đã làm phiền tôi từ lâu.
Tất cả chúng ta đều được dạy ở trường (ít nhất là tôi) rằng bạn PHẢI giải phóng mọi con trỏ được phân bổ. Tuy nhiên, tôi hơi tò mò về chi phí thực sự của việc không giải phóng bộ nhớ. Trong một số trường hợp rõ ràng, như khi malloc
được gọi bên trong vòng lặp hoặc một phần của thực thi luồng, điều đó rất quan trọng để giải phóng để không bị rò rỉ bộ nhớ. Nhưng hãy xem xét hai ví dụ sau:
Đầu tiên, nếu tôi có mã giống như thế này:
int main()
{
char *a = malloc(1024);
/* Do some arbitrary stuff with 'a' (no alloc functions) */
return 0;
}
Kết quả thực sự ở đây là gì? Suy nghĩ của tôi là quá trình chết đi và sau đó không gian heap biến mất nên không có hại khi bỏ lỡ cuộc gọi free
(tuy nhiên, tôi nhận ra tầm quan trọng của việc dù sao đi nữa để đóng, duy trì và thực hành tốt). Tôi có đúng trong suy nghĩ này không?
Thứ hai, giả sử tôi có một chương trình hoạt động giống như một cái vỏ. Người dùng có thể khai báo các biến như aaa = 123
và các biến được lưu trữ trong một số cấu trúc dữ liệu động để sử dụng sau. Rõ ràng, có vẻ như rõ ràng rằng bạn sẽ sử dụng một số giải pháp sẽ gọi một số hàm * alloc (hashmap, danh sách được liên kết, đại loại như thế). Đối với loại chương trình này, sẽ không có ý nghĩa bao giờ miễn phí sau khi gọi malloc
vì các biến này phải có mặt mọi lúc trong quá trình thực hiện chương trình và không có cách nào tốt (mà tôi có thể thấy) để thực hiện điều này với không gian được phân bổ tĩnh. Có phải là thiết kế tồi khi có một loạt bộ nhớ được phân bổ nhưng chỉ được giải phóng như một phần của quá trình kết thúc? Nếu vậy, những gì thay thế?
free(a)
không thực sự làm bất cứ điều gì để thực sự giải phóng bộ nhớ! Nó chỉ đơn thuần đặt lại một số gợi ý trong việc triển khai libc của malloc, theo dõi các khối bộ nhớ có sẵn trong một trang bộ nhớ lớn (thường được gọi là "heap"). Trang đó vẫn sẽ chỉ được giải phóng khi chương trình của bạn chấm dứt chứ không phải trước đó.