2012-03-20 3 views
37

Zastanawiam się, dlaczego takie funkcje jak:
-memset
-memmov
-memchr
-memcpy
Dlaczego funkcje pamięci takie jak memset, memchr ... są w ciąg.h, ale nie w stdlib.h z innymi funkcjami mem?

Exist w string.h pliku nagłówka, ale nie w stdlib.h pliku, gdzie istnieją inne standardowe funkcje pamięci jako dynamiczne przydzielanie pamięci: malloc, calloc, realloc, free.

Może lepiej byłoby je zjednoczyć w jednym nagłówku? Co o tym myślisz? Nie rozumiem, dlaczego jeden zestaw funkcji pamięci jest oddzielony od innych i istnieje w nagłówku napisu (string.h).

+1

To wygląda na problem z implementacją biblioteki C, z której korzystasz. Inna biblioteka C może przenieść memcpy na stdlib. – AgA

+1

'malloc' i rodzina zajmują się dynamicznym przydzielaniem pamięci. 'memcpy' i rodzina radzą sobie z sekwencjami bajtów. 'strcpy' i rodzina również zajmują się sekwencjami bajtów, w nieco inny sposób. –

+5

@AgA: Jeśli biblioteka C jest zgodna ze standardem ISO, to 'memcpy' będzie w' string.h', a nie 'stdlib.h'. – Blastfurnace

Odpowiedz

30

Ponieważ faktycznie string.h jest zdefiniowany jako standardowy nagłówek, który deklaruje funkcje traktujące tablicę znaków, a nie tylko ciągi. Funkcje takie jak memcpy i memset pobierają argumenty, które są traktowane jako wskaźniki do pierwszego elementu obiektu typu tablica znaków.

(C99, 7.21.1p1) Nagłówek < string.h> deklaruje kilka funkcji jednego rodzaju i, i określa jedną makro użyteczny do manipulowania tablice typu znakowego i innych obiektów traktowanych jako tablice typu znaków.

+2

ale takie metody jak memset, memchr, memmov, memcpy działają z void * type i naprawdę więcej pamięci działa char, mam rację? –

+2

Można przekazać dowolny typ wskaźnika obiektu, ale elementy tablicy są w rzeczywistości interpretowane tak, jakby miały typ "unsigned char". (C99, 7.21.1p3) – ouah

+1

Również w odniesieniu do 'void *', zauważ, że w K & R C (pre-Standard C) nie było typu 'void' i parametry funkcji' memcpy' i 'memset' były'. char * 'type a nie' void * '. – ouah

10

Nie będę naprawdę myślał o funkcjach string.h jako "pamięci". Zamiast tego uważałbym je za funkcje "tablicowe", ponieważ działają one na danych zawartych w sekwencjach pamięci. Natomiast, malloc (i inne), faktycznie zapewniają usługi pamięci, takie jak przydzielanie, zamiast manipulowania danymi w regionie pamięci.

W szczególności funkcje w string.h nie zajmują się przydzielaniem lub zwalnianiem pamięci lub jakąkolwiek formą zarządzania pamięcią. Nawet funkcja taka jak char * strerror(int), która wydaje się tworzyć cały nowy ciąg, nie wykonuje żadnych alokacji, ponieważ zwracana wartość jest w rzeczywistości statycznie przydzielonym łańcuchem. Pozostałe funkcje mogą zwrócić wskaźnik do bloku pamięci, ale jest to właściwie jeden z ich parametrów (np. memcpy). Lub zwracają wskaźnik do początku pod-ciągu znaków (strtok) lub liczby całkowitej reprezentującej porównanie (memcmp).

Z drugiej strony, stdlib.h również nie zajmuje się pamięcią. Projekt stdlib.h ma na celu zapewnienie operacji ogólnego przeznaczenia, których prawdopodobnie będzie potrzebować duża liczba programów. Funkcje pamięci są tylko przykładami takich podstawowych operacji. Jednak inne funkcje, takie jak exit i system są również dobrymi przykładami, ale nie dotyczą pamięci.

Teraz istnieją pewne funkcje w stdlib.h które IMO mogło być umieszczone w string.h, szczególnie różne funkcje konwersji (mbstowcs, wcstombs, atoi, strtod, etc.), a może nawet funkcje bsearch i qsort. Funkcje te są zgodne z tymi samymi zasadami, co funkcje string.h (działają na tablicach, nie zwracają nowo przydzielonych bloków pamięci itp.).

Ale z praktycznego punktu widzenia, nawet jeśli popełnił wiele sensu łączyć funkcje mem* z funkcjami malloc, realloc, calloc i free, biblioteka standardowa C jest nigdy będzie zreorganizowany tak. Taka zmiana zdecydowanie złamałaby kod. Ponadto, stdlib.h i string.h istnieją od tak dawna i są zarówno użytecznymi, jak i podstawowymi bibliotekami, które prawdopodobnie spowodowałyby najwięcej (lub przynajmniej dużo) zmian kodu.

3

We wstępnym standardzie C funkcje te zostały zdefiniowane gdzie indziej, ale nie w stdlib.h ani w żadnym z pozostałych standardowych nagłówków, ale w memory.h. Wciąż może istnieć w twoim systemie, na pewno nadal działa na OS X (od dzisiaj).

memory.h na OS X 10.11 (bez nagłówka licencji):

#include <string.h> 

Cały plik jest tylko #include „ing string.h, aby zachować wsteczną kompatybilność z programami Pre-standard C.

Powiązane problemy