2011-09-28 11 views
20

Eventuali duplicati:
Why calloc takes two arguments while malloc only one?In che modo malloc e calloc sono finiti con diverse firme?

Ci sono un sacco delle risorse che descrivono la differenza di funzionalità tra malloc e calloc, ma non riesco a trovare facilmente quello che descrive la storia dietro le diverse firme di funzioni:

void *calloc(size_t nmemb, size_t size); 
    void *malloc(size_t size); 

Ovviamente, lo size nel primo è la dimensione per ciascun membro. Forse l'idea era che i callocs delle dimensioni dei membri di dimensioni multiple della pagina potevano essere eseguiti pigramente tramite il sistema operativo?

(posso compensare motivi così come il prossimo ragazzo -. Risposte non accettati senza fonti citate :-)

+0

Estremamente correlato: http://stackoverflow.com/q/7536413/142019 –

+1

Nessuna citazione, quindi solo un commento - la firma 'calloc' è più utilizzabile, dal momento che una corretta implementazione controlla l'overflow in multiplo, alleviando il chiamante della responsabilità. Sospetto una delle due spiegazioni: (1) 'malloc' è venuto prima, ed è solo una cosa di compatibilità, (2)' calloc' dovrebbe essere più lento a causa dello zero-ing, e qualcuno ha pensato che il controllo di moltiplicazione e overflow in 'malloc' dovrebbe essere omesso per la velocità. –

+0

Trovo strano che una domanda possa essere chiusa come un duplicato esatto di una domanda meno specifica senza risposte soddisfacenti (o accettate) - Mi chiedo come siano sorte storicamente le due firme. – cdleary

risposta

1

Questo è un po 'suscettibile di interpretazione del linguaggio usato nella specifica C.

Il linguaggio qui sembra scelto molto attentamente - malloc viene definita nella sezione 7.20.3.3 come:

La funzione malloc alloca spazio per un oggetto la cui dimensione è specificato da dimensioni e il cui valore è indeterminato.

precedenza un oggetto è stato definito nella sezione 3.14 come:

regione di memorizzazione dei dati in ambiente di esecuzione, i cui contenuto può rappresentare valori

calloc dall'altro è definito in 7.20.3.1 come:

La funzione calloc alloca lo spazio per un array di oggetti nmemb, ciascuna delle cui dimensioni è la dimensione. Lo spazio è inizializzato su tutti i bit zero.

Questo dovrebbe rendere evidente. La differenza tra calloc e malloc è che calloc alloca la memoria per una matrice di n oggetti concettuali, sebbene in pratica ciò non sia diverso da una chiamata a malloc che alloca lo spazio per 1 oggetto concettuale di dimensione (n * dimensione).

Quindi la domanda successiva è ... qual è la necessità della distinzione tra lo spazio per una matrice di oggetti e lo spazio per un grande oggetto?

Dal punto di vista dei programmatori, le due chiamate di funzione richiedono solo cose diverse. Uno sta chiedendo di assegnare un grosso pezzo di memoria - e mi occuperò di esso. L'altro sta dicendo: Voglio una serie di n cose di queste dimensioni, dammi un po 'di memoria che potrei usare per questo array e azzerarlo, perché nella maggior parte delle implementazioni posso fare delle buone assunzioni su cosa significhi memoria azzerata.

Il fatto che si stia tentando di usarlo come malloc + azzeramento è, dalla lettura delle specifiche, un fraintendimento sullo scopo della funzione.

Hanno finito con diverse firme perché fanno cose diverse.


Alcuni pensieri laterali carino ... Un'implementazione malloc banale può sembrare:

#define malloc(x) (calloc(1, x)) 

E 'anche divertente notare che se mia rappresentazione puntatore NULL non viene azzerato, quindi calloc no restituiscimi una serie di puntatori NULL. Meglio ancora, se progetto una rappresentazione intera in cui la memoria azzerata non è ((int) 0), calloc non mi restituirà un array di 0.

+0

Quindi stai dicendo che 'calloc' restituisce un array di oggetti inizializzati (ammesso che all-bit-zero non sia garantito come un oggetto valido per tutti i tipi su tutte le implementazioni, è almeno un ragionevole tentativo di inizializzazione), mentre 'malloc' restituisce la memoria non inizializzata non elaborata per un oggetto o un array? –

+0

Per quanto riguarda le tue note divertenti - potresti infatti progettare un'implementazione in cui tutto-bit-zero è una rappresentazione trap di ogni tipo eccetto 'char' e' signed/unsigned char', rendendo 'calloc' quasi inutile. Come corollario, 'calloc' è quasi inutile in programmi strettamente conformi, e il suo secondo parametro è del tutto inutile in programmi strettamente conformi poiché l'unico tipo è utile per avere la dimensione 1. –

+0

@Steve Jessop: Le rappresentazioni di trap non sono un problema finchè poiché non li valuti, puoi sovrascriverli semplicemente in un programma strettamente conforme. – caf

Problemi correlati