Trong các chương trình C của tôi, tôi thường cần một cách để thể hiện chuỗi ADT của mình. Ngay cả khi tôi không cần phải in chuỗi lên màn hình theo bất kỳ cách nào, thật gọn gàng khi có phương pháp như vậy để gỡ lỗi. Vì vậy, loại chức năng này thường xuất hiện.
char * mytype_to_string( const mytype_t *t );
Tôi thực sự nhận ra rằng tôi có (ít nhất) ba tùy chọn ở đây để xử lý bộ nhớ cho chuỗi trả về.
Thay thế 1: Lưu trữ chuỗi trả về trong một mảng char tĩnh trong hàm. Tôi không cần suy nghĩ nhiều, ngoại trừ chuỗi được ghi đè trong mỗi cuộc gọi. Mà có thể là một vấn đề trong một số trường hợp.
Phương án 2: Phân bổ chuỗi trên heap với malloc bên trong hàm. Thực sự gọn gàng vì sau đó tôi sẽ không cần phải nghĩ đến kích thước của bộ đệm hoặc ghi đè. Tuy nhiên, tôi phải nhớ để giải phóng () chuỗi khi hoàn thành, và sau đó tôi cũng cần gán cho một biến tạm thời để tôi có thể giải phóng. và sau đó phân bổ heap thực sự chậm hơn nhiều so với phân bổ stack, do đó, sẽ là một nút cổ chai nếu điều này được lặp lại trong một vòng lặp.
Phương án 3: Truyền con trỏ vào bộ đệm và để người gọi phân bổ bộ đệm đó. Giống:
char * mytype_to_string( const mytype_t *mt, char *buf, size_t buflen );
Điều này mang lại nhiều nỗ lực hơn cho người gọi. Tôi cũng nhận thấy rằng sự thay thế này mang lại cho tôi một lựa chọn khác theo thứ tự của các đối số. Tôi nên có đối số nào trước và cuối? (thực tế là sáu khả năng)
Vì vậy, tôi nên chọn cái nào? Bất kỳ tại sao? Có một số loại tiêu chuẩn bất thành văn trong số các nhà phát triển C?
sysctlbyname
trong OS X và iOS