2012-03-20 12 views
37

Mi chiedo, perché tale funzione come:
-memset
-memmov
-memchr
-memcpy
Perché le funzioni di memoria come memset, memchr ... sono in string.h, ma non in stdlib.h con altre funzioni di mem?

Esiste nel file di intestazione string.h, ma non nel file di stdlib.h, dove ci sono altre funzioni di memoria standard come allocazione dinamica della memoria: malloc, calloc, realloc, gratis.

Forse sarebbe meglio unirli in un'unica intestazione? Cosa ne pensi? Non capisco, perché una serie di funzioni di memoria sono separate dalle altre e esistono nell'intestazione di stringa (string.h).

+1

Questo sembra un problema di implementazione con la libreria C che si sta utilizzando. Altre librerie C possono scegliere di spostare memcpy in stdlib. – AgA

+1

'malloc' e famiglia occupano l'allocazione dinamica della memoria. 'memcpy' e la famiglia si occupano di sequenze di byte. 'strcpy' e la famiglia si occupano anche di sequenze di byte, in un modo leggermente diverso. –

+5

@AgA: se una libreria C è conforme allo standard ISO allora 'memcpy' sarà in' string.h', non 'stdlib.h'. – Blastfurnace

risposta

30

Perché in realtà string.h è definito come un'intestazione standard che dichiara le funzioni che trattano l'array di caratteri e non solo le stringhe. Funzioni come memcpy e memset accettano argomenti che vengono considerati come puntatori al primo elemento di un oggetto di tipo matrice di caratteri.

(C99, 7.21.1p1) L'intestazione < string.h> dichiara tipo e diverse funzioni, e definisce una macro utile per manipolare array di tipo carattere e altri oggetti trattati come array di tipo carattere.

+2

ma metodi come memset, memchr, memmov, memcpy funzionano con il tipo void * e molto più funzionano la memoria non char, ho ragione? –

+2

È possibile passare qualsiasi tipo di puntatore a oggetti, ma gli elementi dell'array vengono infatti interpretati come se avessero il tipo 'unsigned char'. (C99, 7.21.1p3) – ouah

+1

Anche per 'void *', si noti che in K & R C (pre-Standard C), non esisteva il tipo 'void' ed i parametri di funzioni come' memcpy' e 'memset' erano di' char * 'type e not' void * '. – ouah

10

Non vorrei davvero pensare alle funzioni string.h come a funzioni di "memoria". Invece, li considererei come funzioni "array", poiché operano sui dati contenuti nelle sequenze di memoria. Al contrario, malloc (e altri), in realtà forniscono servizi di memoria come l'allocazione, piuttosto che la manipolazione dei dati all'interno di una regione di memoria.

In particolare, le funzioni in string.h non si occupano di allocazioni o deallocuzioni di memoria o di qualsiasi forma di gestione della memoria. Anche una funzione come char * strerror(int), che sembra creare un'intera nuova stringa, non esegue alcuna allocazione, poiché il valore restituito è in realtà una stringa allocata staticamente. Le altre funzioni potrebbero restituire un puntatore a un blocco di memoria, ma questo è in realtà solo uno dei loro parametri (ad esempio memcpy). Oppure restituiscono un puntatore all'inizio di una sottostringa (strtok) o un numero intero che rappresenta un confronto (memcmp).

D'altra parte, stdlib.h non si riferisce alla memoria. Il design di stdlib.h è quello di fornire operazioni di carattere generale che necessitano di un numero elevato di programmi. Le funzioni di memoria sono solo esempi di operazioni fondamentali. Tuttavia, altre funzioni come exit e system sono anche buoni esempi, ma non si applicano alla memoria.

Ora ci sono alcune funzioni in stdlib.h che IMO possa essere posizionata in string.h, in particolare le varie funzioni di conversione (mbstowcs, wcstombs, atoi, strtod, ecc), e forse anche le bsearch e qsort funzioni. Queste funzioni seguono gli stessi principi delle funzioni string.h (funzionano sugli array, non restituiscono blocchi di memoria appena allocati, ecc.).

Ma da un punto di vista pratico, anche se ha fatto un sacco di senso di combinare le funzioni mem* con le funzioni malloc, realloc, calloc e free, la libreria standard C è mai intenzione di essere riorganizzato come questo. Un tale cambiamento avrebbe sicuramente infranto il codice. Inoltre, stdlib.h e string.h sono in circolazione da così tanto tempo, e sono entrambe librerie utili e fondamentali, che le modifiche probabilmente infrangerebbero la maggior parte (o almeno un sacco) codice C.

3

In Pre-Standard C, queste funzioni erano effettivamente definite da qualche altra parte, ma né in stdlib.h né in altre intestazioni standard, ma in memory.h. Potrebbe ancora esistere sul tuo sistema, sicuramente lo fa ancora su OS X (fino ad oggi).

memory.h su OS X 10.11 (senza intestazione licenza):

#include <string.h> 

l'intero file è solo #include 'ing string.h, per mantenere la compatibilità con i programmi pre-standard C.

Problemi correlati