Cá nhân; Tôi có một thư viện theo dõi tài nguyên (về cơ bản là một cây nhị phân cân bằng) và tôi có trình bao bọc cho tất cả các chức năng phân bổ.
Tài nguyên (chẳng hạn như bộ nhớ, ổ cắm, bộ mô tả tệp, ẩn dụ, v.v ... - bất kỳ thứ gì bạn phân bổ và deallocate) có thể thuộc về một tập hợp.
Tôi cũng có một thư viện xử lý lỗi, theo đó đối số đầu tiên cho mỗi hàm là một bộ lỗi và nếu xảy ra sự cố, hàm sẽ gặp lỗi khi gửi lỗi vào bộ lỗi.
Nếu bộ lỗi có lỗi, không có chức năng nào thực thi. (Tôi có một macro ở trên cùng của mọi chức năng mà làm cho nó trở lại).
Vì vậy, nhiều malloc trông như thế này;
mem[0] = malloc_wrapper(error_set, resource_set, 100);
mem[1] = malloc_wrapper(error_set, resource_set, 50);
mem[2] = malloc_wrapper(error_set, resource_set, 20);
Không cần để kiểm tra giá trị trả về, vì nếu một lỗi xảy ra, không có chức năng sau đây sẽ thực hiện, ví dụ mallocs sau không bao giờ xảy ra. Vì vậy, khi thời gian đến cho tôi để deallocate tài nguyên (nói ở phần cuối của một chức năng, nơi mà tất cả các nguồn lực được sử dụng nội bộ bởi chức năng đó đã được đặt vào một bộ), tôi deallocate bộ. Nó chỉ là một cuộc gọi hàm.
res_delete_set(resource_set);
Tôi không cần phải kiểm tra đặc biệt cho lỗi - có không if() s trong mã của tôi kiểm tra giá trị trả lại, mà làm cho nó duy trì; Tôi thấy sự gia tăng của kiểm tra lỗi trong dòng phá hủy khả năng đọc và do đó bảo trì. Tôi chỉ có một danh sách các lệnh gọi hàm.
Đó là nghệ thuật, người đàn ông :-)
là tốt trong các tình huống nhất định. Chúng tôi thấy loại dọn dẹp này trong hạt nhân Linux rất nhiều. Nó hoạt động tốt và dễ hiểu. –
@Steve Lazaridis: Chính xác. Làm việc với nhân Linux đã dạy tôi rằng đôi khi, goto là ok. :) – FreeMemory
Điều đó sẽ không hoạt động đáng tin cậy trừ khi bạn đặt trước * mem1 và * mem2. –