2012-03-20 24 views
37

Tôi tự hỏi, tại sao chức năng như:
-memset
-memmov
-memchr
-memcpy
Tại sao chức năng bộ nhớ như memset, memchr ... có trong chuỗi.h, nhưng không phải trong stdlib.h với một chức năng ghi nhớ khác?

tồn tại trong tập tin tiêu đề string.h, nhưng không phải trong tập tin stdlib.h, nơi có các chức năng bộ nhớ tiêu chuẩn khác như cấp phát bộ nhớ động: malloc, calloc, realloc, miễn phí.

Có lẽ sẽ tốt hơn nếu kết hợp chúng trong một tiêu đề? Bạn nghĩ gì về nó? Tôi không hiểu, tại sao một tập hợp các chức năng bộ nhớ được tách ra khỏi những người khác và tồn tại trong tiêu đề chuỗi (string.h).

+1

Điều này giống như vấn đề triển khai với thư viện C bạn đang sử dụng. Thư viện C khác có thể chọn chuyển memcpy sang stdlib. – AgA

+1

'malloc' và gia đình đối phó với phân bổ bộ nhớ động. 'memcpy' và gia đình đối phó với chuỗi byte. 'strcpy' và gia đình cũng đối phó với chuỗi byte, theo một cách hơi khác. –

+5

@AgA: Nếu thư viện C tuân theo tiêu chuẩn ISO thì 'memcpy' sẽ nằm trong' string.h', không phải 'stdlib.h'. – Blastfurnace

Trả lời

30

Bởi vì thực tế string.h được định nghĩa là tiêu đề chuẩn khai báo các hàm xử lý mảng ký tự chứ không chỉ các chuỗi. Các hàm như memcpymemset lấy đối số được coi là con trỏ tới phần tử đầu tiên của đối tượng của mảng kiểu ký tự.

(C99, 7.21.1p1) Tiêu đề < string.h> tuyên bố một loại và một số chức năng, và định nghĩa một macro hữu ích để thao tác với mảng kiểu nhân vật và các đối tượng khác đối xử như mảng loại nhân vật.

+2

nhưng các phương pháp như memset, memchr, memmov, memcpy làm việc với void * loại và thực sự nhiều công trình bộ nhớ không char, tôi phải không? –

+2

Bạn có thể chuyển bất kỳ kiểu con trỏ đối tượng nào, nhưng các phần tử mảng trong thực tế được hiểu là chúng có kiểu 'unsigned char'. (C99, 7.21.1p3) – ouah

+1

Cũng liên quan đến 'void *', lưu ý rằng trong K & R C (chuẩn C), không có loại 'void' và các tham số của các hàm như' memcpy' và 'memset' là của' char * 'loại và không' void * '. – ouah

10

Tôi sẽ không thực sự nghĩ về các chức năng string.h là chức năng "bộ nhớ". Thay vào đó, tôi sẽ coi chúng là các hàm "mảng", vì chúng hoạt động trên dữ liệu nằm trong dãy bộ nhớ. Ngược lại, malloc (và những người khác), thực sự cung cấp các dịch vụ bộ nhớ như phân bổ, thay vì thao tác dữ liệu trong một vùng bộ nhớ.

Cụ thể, các chức năng trong string.h không quan tâm đến việc cấp phát hoặc phân bổ bộ nhớ hoặc bất kỳ hình thức quản lý bộ nhớ nào. Ngay cả một hàm như char * strerror(int), xuất hiện để tạo ra một chuỗi hoàn toàn mới, không thực hiện bất kỳ phân bổ nào, bởi vì giá trị trả về thực sự là một chuỗi được phân bổ tĩnh. Các hàm khác có thể trả về một con trỏ tới một khối bộ nhớ, nhưng đây thực sự chỉ là một trong các tham số của chúng (ví dụ: memcpy). Hoặc họ trả về một con trỏ để bắt đầu một chuỗi con (strtok), hoặc một số nguyên đại diện cho một so sánh (memcmp).

Mặt khác, stdlib.h cũng không thực sự là về bộ nhớ. Thiết kế của stdlib.h là cung cấp các hoạt động có mục đích chung mà một số lượng lớn các chương trình có thể sẽ cần. Các chức năng bộ nhớ chỉ xảy ra là các ví dụ về các hoạt động cơ bản như vậy. Tuy nhiên, các chức năng khác như exitsystem cũng là các ví dụ hay, nhưng không áp dụng cho bộ nhớ.

Bây giờ có một số chức năng trong stdlib.h mà IMO có thể đã được đặt trong string.h, đặc biệt là chức năng khác nhau chuyển đổi (mbstowcs, wcstombs, atoi, strtod, vv), và thậm chí có những bsearchqsort chức năng. Các chức năng này tuân theo các nguyên tắc tương tự như các hàm string.h (chúng hoạt động trên các mảng, không trả về các khối bộ nhớ mới được cấp phát, v.v.).

Nhưng từ góc độ thực tế, ngay cả khi nó làm cho rất nhiều ý nghĩa để kết hợp các mem* chức năng với các chức năng malloc, realloc, callocfree, các thư viện chuẩn C là bao giờ sẽ được tổ chức lại như thế này. Một thay đổi như vậy chắc chắn sẽ phá vỡ mã. Ngoài ra, stdlib.hstring.h đã tồn tại quá lâu và cả hai thư viện hữu ích và cơ bản như vậy, rằng những thay đổi có thể sẽ phá vỡ hầu hết (hoặc ít nhất, rất nhiều) mã C.

3

Trong chuẩn C, các chức năng này thực sự được xác định ở một nơi khác, nhưng không phải trong stdlib.h cũng như trong bất kỳ tiêu đề chuẩn nào khác, nhưng trong memory.h. Nó vẫn có thể tồn tại trên hệ thống của bạn, nó chắc chắn vẫn còn trên OS X (tính đến hôm nay).

memory.h trên OS X 10.11 (không có tiêu đề giấy phép):

#include <string.h> 

Toàn bộ tập tin chỉ #include là 'ing string.h, để duy trì tính tương thích ngược với các chương trình Pre-Tiêu chuẩn C.

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