Differenza tra malloc e calloc?


780

Qual è la differenza tra fare:

ptr = (char **) malloc (MAXELEMS * sizeof(char *));

o:

ptr = (char **) calloc (MAXELEMS, sizeof(char*));

Quando è una buona idea usare calloc su malloc o viceversa?



8
In C, potresti scrivere quanto sopra in modo più generico come:ptr = calloc(MAXELEMS, sizeof(*ptr));
chqrlie,

7
Un post interessante sulla differenza tra calloc e malloc + memset vorpus.org/blog/why-does-calloc-exist
ddddavidee

2
@ddddavidee Anch'io ho trovato quel blog dopo essere stato insoddisfatto di così tante risposte in rete. Nathaniel J. Smith merita oltre 100 punti SO per la sua analisi.
lifebalance

Risposte:


851

calloc()ti dà un buffer zero inizializzato, mentre malloc()lascia la memoria non inizializzata.

Per allocazioni di grandi dimensioni, la maggior parte delle callocimplementazioni nei sistemi operativi tradizionali otterrà pagine azzerate dal sistema operativo (ad esempio tramite POSIX mmap(MAP_ANONYMOUS)o Windows VirtualAlloc), quindi non è necessario scriverle nello spazio utente. Questo è come normale mallocottiene anche più pagine dal sistema operativo; callocsfrutta solo la garanzia del sistema operativo.

Ciò significa che la callocmemoria può ancora essere "pulita" e allocata pigramente, e copia su scrittura mappata su una pagina fisica condivisa a livello di sistema di zeri. (Supponendo un sistema con memoria virtuale.)

Alcuni compilatori possono anche ottimizzare malloc + memset (0) in calloc per te, ma dovresti usare calloc esplicitamente se vuoi che la memoria legga come 0.

Se non leggerai mai la memoria prima di scriverla, usala in mallocmodo che possa (potenzialmente) fornirti memoria sporca dalla sua lista libera interna invece di ottenere nuove pagine dal sistema operativo. (O invece di azzerare un blocco di memoria nella lista libera per una piccola allocazione).


Le implementazioni incorporate callocpossono lasciare a callocse stesso la memoria zero se non c'è un sistema operativo, o non è un sistema operativo multiutente sofisticato che azzera le pagine per bloccare la fuga di informazioni tra i processi.

Su Linux incorporato, malloc potrebbe mmap(MAP_UNINITIALIZED|MAP_ANONYMOUS), che è abilitato solo per alcuni kernel incorporati perché non è sicuro su un sistema multiutente.


224
Le varianti * alloc sono piuttosto mnemoniche: clear-alloc, memory-alloc, re-alloc.
Cascabel,

43
Usa malloc () se hai intenzione di impostare tutto ciò che usi nello spazio allocato. Usa calloc () se vuoi lasciare parti dei dati non inizializzate - e sarebbe utile avere azzerate le parti non impostate.
Jonathan Leffler,

268
callocnon è necessariamente più costoso, poiché il sistema operativo può fare alcuni trucchi per accelerarlo. So che FreeBSD, quando ottiene qualsiasi tempo di inattività della CPU, lo usa per eseguire un semplice processo che va in giro e azzera i blocchi di memoria deallocati, e contrassegna i blocchi così i processi con una bandiera. Quindi, quando lo fai calloc, cerca prima di trovare uno di questi blocchi pre-azzerati e dartelo, e molto probabilmente lo troverà.
Pavel Minaev,

28
Tendo a pensare che se il tuo codice diventa "più sicuro" come risultato delle allocazioni zero-initing di default, allora il tuo codice non è sufficientemente sicuro se usi malloc o calloc. L'uso di malloc è un buon indicatore del fatto che i dati necessitano di inizializzazione: uso calloc solo nei casi in cui questi 0 byte sono effettivamente significativi. Si noti inoltre che calloc non necessariamente fa ciò che si pensa per i tipi non char. Nessuno usa più le rappresentazioni di trap o float non IEEE, ma non è una scusa per pensare che il tuo codice sia veramente portatile quando non lo è.
Steve Jessop,

18
@SteveJessop "Più sicuro" non è la parola corretta. Penso che "deterministico" sia il termine migliore. Il codice che è più deterministico piuttosto che avere guasti che dipendono dal tempo e dalle sequenze di dati, sarà più facile isolare i guasti. Calloc è talvolta un modo semplice per ottenere quel determinismo, rispetto all'inizializzazione esplicita.
dennis,

362

Una differenza meno nota è che nei sistemi operativi con allocazione ottimistica della memoria, come Linux, il puntatore restituito mallocnon è supportato dalla memoria reale fino a quando il programma non lo tocca.

calloctocca davvero la memoria (scrive zero su di essa) e quindi sarai sicuro che il sistema operativo stia supportando l'allocazione con RAM effettiva (o swap). Questo è anche il motivo per cui è più lento di malloc (non solo deve azzerarlo, ma anche il sistema operativo deve trovare un'area di memoria adatta scambiando eventualmente altri processi)

Vedi ad esempio questa domanda SO per ulteriori discussioni sul comportamento del malloc


49
callocnon è necessario scrivere zeri. Se il blocco allocato è costituito principalmente da nuove pagine zero fornite dal sistema operativo, può lasciare intatte quelle. Questo ovviamente richiede callocdi essere sintonizzato sul sistema operativo piuttosto che su una funzione di libreria generica malloc. Oppure, un implementatore potrebbe callocconfrontare ogni parola con zero prima di azzerarla. Ciò non farebbe risparmiare tempo, ma eviterebbe di sporcare le nuove pagine.
R .. GitHub FERMA DI AIUTARE ICE il

3
@R .. nota interessante. Ma in pratica, esistono tali implementazioni in natura?
Isak Savo

10
Le dlmallocimplementazioni a tutto tondo saltano memsetse il blocco è stato ottenuto tramite mmapnuove pagine anonime (o equivalenti). Di solito questo tipo di allocazione viene utilizzato per blocchi più grandi, a partire da 256k circa. Non conosco alcuna implementazione che faccia il confronto con zero prima di scrivere zero a parte il mio.
R .. GitHub smette di aiutare ICE il

1
omallocsalta anche il memset; callocnon deve mai toccare pagine che non sono già utilizzate dall'applicazione (cache della pagina). Tuttavia, le callocimplementazioni estremamente primitive differiscono.
mirabilos,

10
il calloc di glibc verifica se sta ricevendo nuova memoria dal sistema operativo. In tal caso, sa che NON è necessario scriverlo, perché mmap (..., MAP_ANONYMOUS) restituisce la memoria già azzerata.
Peter Cordes,

112

Un vantaggio spesso trascurato callocè che (implementazioni conformi di) ti aiuteranno a proteggerti da vulnerabilità di overflow di numeri interi. Confrontare:

size_t count = get_int32(file);
struct foo *bar = malloc(count * sizeof *bar);

vs.

size_t count = get_int32(file);
struct foo *bar = calloc(count, sizeof *bar);

Il primo potrebbe comportare una piccola allocazione e successivi buffer overflow, se countè maggiore di SIZE_MAX/sizeof *bar. Quest'ultimo fallirà automaticamente in questo caso poiché non è possibile creare un oggetto così grande.

Ovviamente potresti dover essere alla ricerca di implementazioni non conformi che semplicemente ignorano la possibilità di overflow ... Se questo è un problema sulle piattaforme target, dovrai comunque eseguire un test manuale per overflow.


17
Apparentemente il trabocco aritmetico è stato ciò che ha causato il buco di OpenSSH nel 2002. Un buon articolo di OpenBSD sui pericoli di questo con funzioni legate alla memoria: undeadly.org/cgi?action=article&sid=20060330071917
Philip P.

4
@KomradeP .: Interessante. Purtroppo l'articolo che hai collegato ha una disinformazione proprio all'inizio. L'esempio con nonchar è un overflow ma piuttosto una conversione definita dall'implementazione quando si riassegna il risultato in un oggetto. char
R .. GitHub smette di aiutare ICE il

Probabilmente è lì solo a scopo illustrativo. Perché il compilatore probabilmente lo ottimizzerà comunque. Il mio si compila in questo asm: push 1.
Philip P.

1
@tristopia: il punto non è che il codice sia sfruttabile su tutte le implementazioni, ma che sia errato senza ipotesi aggiuntive e quindi non sia un uso corretto / portatile.
R .. GitHub smette di aiutare ICE il

3
@tristopia: se il tuo modo di pensare è " size_tè a 64 bit, quindi non è un problema", questo è un modo errato di pensare che porterà a bug di sicurezza. size_tè un tipo astratto che rappresenta le dimensioni e non c'è motivo di pensare che il prodotto arbitrario di un numero a 32 bit e un size_t(nota: sizeof *barpotrebbe in linea di principio essere maggiore di 2 ^ 32 su un'implementazione C a 64 bit!) size_t.
R .. GitHub FERMA AIUTANDO ICE

37

La documentazione fa apparire il calloc come malloc, che azzera la memoria; questa non è la differenza principale! L'idea di calloc è di interrompere la semantica copy-on-write per l'allocazione della memoria. Quando si alloca memoria con calloc, tutto viene mappato sulla stessa pagina fisica inizializzata su zero. Quando una delle pagine della memoria allocata viene scritta in una pagina fisica viene allocata. Questo è spesso usato per creare tabelle hash ENORMI, ad esempio poiché le parti di hash che sono vuote non sono supportate da memoria aggiuntiva (pagine); fanno felicemente riferimento alla singola pagina a inizializzazione zero, che può anche essere condivisa tra i processi.

Qualsiasi scrittura su indirizzo virtuale viene mappata su una pagina, se quella pagina è la pagina zero, viene allocata un'altra pagina fisica, la pagina zero viene copiata lì e il flusso di controllo viene restituito al processo client. Funziona allo stesso modo dei file mappati in memoria, della memoria virtuale, ecc. Funziona con il paging.

Ecco una storia di ottimizzazione sull'argomento: http://blogs.fau.de/hager/2007/05/08/benchmarking-fun-with-calloc-and-zero-pages/


26

Non vi è alcuna differenza nella dimensione del blocco di memoria allocato. callocriempie semplicemente il blocco di memoria con un modello fisico a zero-bit. In pratica si presume spesso che gli oggetti situati nel blocco di memoria allocato con callocabbiano valore iniziale come se fossero inizializzati con 0valori letterali , cioè gli interi dovrebbero avere valore di 0variabili a virgola mobile - valore di 0.0, puntatori - il valore puntatore null appropriato , e così via.

Dal punto di vista pedante, però, calloc(così come memset(..., 0, ...)) è garantito solo per inizializzare correttamente (con zero) oggetti di tipo unsigned char. Non è garantito che tutto il resto sia inizializzato correttamente e potrebbe contenere la cosiddetta rappresentazione trap , che provoca un comportamento indefinito. In altre parole, per qualsiasi tipo diverso unsigned chardal summenzionato patterm a zero bit potrebbe rappresentare un valore illegale, rappresentazione trap.

Successivamente, in una delle rettifiche tecniche conformi allo standard C99, il comportamento è stato definito per tutti i tipi di numeri interi (il che ha senso). Vale a dire formalmente, nel linguaggio C corrente è possibile inizializzare solo i tipi interi con calloc(e memset(..., 0, ...)). Usarlo per inizializzare qualsiasi altra cosa nel caso generale porta a un comportamento indefinito, dal punto di vista del linguaggio C.

In pratica, callocfunziona, come tutti sappiamo :), ma se vuoi usarlo (considerando quanto sopra) dipende da te. Personalmente preferisco evitarlo completamente, usare mallocinvece ed eseguire la mia inizializzazione.

Infine, callocè necessario un altro dettaglio importante per calcolare internamente la dimensione finale del blocco , moltiplicando la dimensione dell'elemento per il numero di elementi. Mentre lo fa, callocdeve fare attenzione al possibile trabocco aritmetico. Si otterrà un'allocazione non riuscita (puntatore nullo) se la dimensione del blocco richiesta non può essere calcolata correttamente. Nel frattempo, la tua mallocversione non tenta di controllare l'overflow. Allocherà una quantità "imprevedibile" di memoria in caso di overflow.


Secondo il paragrafo "un altro dettaglio importante": questo sembra creare memset(p, v, n * sizeof type);un problema perché n * sizeof typepotrebbe traboccare. Immagino che dovrò usare un for(i=0;i<n;i++) p[i]=v;loop per un codice affidabile.
chux - Ripristina Monica il

Sarebbe utile se esistesse un mezzo standard con cui il codice potrebbe affermare che un'implementazione deve usare all-bit-zero come puntatore null (rifiutando altrimenti la compilazione), poiché esistono implementazioni che usano altre rappresentazioni puntatore null, ma sono relativamente raro; il codice che non deve essere eseguito su tali implementazioni può essere più veloce se può usare calloc () o memset per inizializzare le matrici di puntatori.
supercat

@chux No, se nesiste un array con elementi in cui un elemento ha le dimensionisizeof type , n*sizeof typenon può overflow, poiché la dimensione massima di qualsiasi oggetto deve essere inferiore a SIZE_MAX.
12431234123412341234123,

@ 12431234123412341234123 True su una dimensione dell'array <=SIZE_MAX , ma non ci sono array qui. Il puntatore restituito da calloc()può puntare alla memoria allocata di quanto superi SIZE_MAX. Molte implementazioni limitano il prodotto dei 2 argomenti calloc()a SIZE_MAX, ma la specifica C non impone quel limite.
chux - Ripristina Monica il

21

da un articolo Benchmarking fun with calloc () e zero pagine sul blog di Georg Hager

Quando si alloca memoria usando calloc (), la quantità di memoria richiesta non viene allocata immediatamente. Invece, tutte le pagine che appartengono al blocco di memoria sono collegate a una singola pagina contenente tutti gli zeri da un po 'di magia MMU (link sotto). Se tali pagine vengono lette solo (il che era vero per gli array b, c e d nella versione originale del benchmark), i dati vengono forniti dalla singola pagina zero, che - ovviamente - si inserisce nella cache. Questo per quanto riguarda i kernel con loop di memoria. Se una pagina viene scritta (indipendentemente da come), si verifica un errore, la pagina "reale" viene mappata e la pagina zero viene copiata in memoria. Questo si chiama copy-on-write, un noto approccio di ottimizzazione (che ho persino insegnato più volte nelle mie lezioni in C ++). Dopo di che,


dov'è il link?
Rupesh Yadav.

2
la prima riga di risposta contiene link al Blog di Georg Hager.
Ashish Chavan,

11

callocè generalmente malloc+memseta 0

In genere è leggermente meglio usare malloc+memsetesplicitamente, specialmente quando stai facendo qualcosa del tipo:

ptr=malloc(sizeof(Item));
memset(ptr, 0, sizeof(Item));

Questo è meglio perché sizeof(Item)è noto al compilatore in fase di compilazione e il compilatore nella maggior parte dei casi lo sostituirà con le migliori istruzioni possibili per azzerare la memoria. D'altra parte, se memsetsta accadendo calloc, la dimensione del parametro dell'allocazione non è compilata nel calloccodice e memsetspesso viene chiamato real , che in genere conterrebbe codice per riempire byte per byte fino al limite lungo, quindi ciclo per riempire memoria in sizeof(long)blocchi e infine riempimento byte per byte dello spazio rimanente. Anche se l'allocatore è abbastanza intelligente da chiamarne un po ' aligned_memset, rimarrà comunque un ciclo generico.

Un'eccezione notevole sarebbe quando si esegue malloc / calloc di un grosso pezzo di memoria (alcuni power_of_two kilobytes) nel qual caso l'allocazione può essere effettuata direttamente dal kernel. Poiché i kernel del sistema operativo in genere azzerano tutta la memoria che forniscono per motivi di sicurezza, calloc abbastanza intelligente potrebbe semplicemente restituirlo senza ulteriore azzeramento. Ancora una volta - se stai semplicemente allocando qualcosa che sai essere piccolo, potresti stare meglio con malloc + memset dal punto di vista delle prestazioni.


+1 per ricordare che un'implementazione generica di una funzionalità in una libreria di sistema non è necessariamente più veloce della stessa operazione nel codice utente.
Patrick Schlüter,

1
C'è anche un secondo punto che rende calloc()più lento di malloc(): la moltiplicazione per la dimensione. calloc()è necessario utilizzare una moltiplicazione generica (se size_tè 64 bit anche i 64 bit molto costosi * 64 bit = operazione 64 bit) mentre il malloc () avrà spesso una costante di tempo di compilazione.
Patrick Schlüter,

4
glibc calloc ha alcune idee intelligenti per decidere come cancellare in modo più efficiente il blocco restituito, ad esempio a volte solo una parte di esso ha bisogno di essere cancellata, e anche una cancellazione srotolata fino a 9 * sizeof (size_t). La memoria è memoria, cancellarla di 3 byte alla volta non sarà più veloce solo perché la utilizzerai per trattenerla struct foo { char a,b,c; };. callocè sempre meglio di malloc+ memset, se hai sempre intenzione di cancellare l'intera mallocregione ed. callocha un controllo attento ma efficace anche per overflow int in elementi size *.
Peter Cordes,

8

Differenza 1:

malloc() di solito alloca il blocco di memoria ed è un segmento di memoria inizializzato.

calloc() alloca il blocco di memoria e inizializza tutto il blocco di memoria su 0.

Differenza 2:

Se consideri la malloc()sintassi, ci vorrà solo 1 argomento. Considera il seguente esempio di seguito:

data_type ptr = (cast_type *)malloc( sizeof(data_type)*no_of_blocks );

Esempio: se si desidera allocare 10 blocchi di memoria per il tipo int,

int *ptr = (int *) malloc(sizeof(int) * 10 );

Se si considera la calloc()sintassi, saranno necessari 2 argomenti. Considera il seguente esempio di seguito:

data_type ptr = (cast_type *)calloc(no_of_blocks, (sizeof(data_type)));

Es: se si desidera allocare 10 blocchi di memoria per il tipo int e inizializzare tutto ciò su ZERO,

int *ptr = (int *) calloc(10, (sizeof(int)));

Somiglianza:

Entrambi malloc()e calloc()restituiranno void * per impostazione predefinita se non sono stati espressi.


E perché mantieni data_type e cast_type diversi?
Esaurito il

7

Ci sono due differenze.
Innanzitutto, è il numero di argomenti. malloc()accetta un singolo argomento (memoria richiesta in byte), mentre calloc()necessita di due argomenti.
In secondo luogo, malloc()non inizializza la memoria allocata, mentre calloc()inizializza la memoria allocata su ZERO.

  • calloc()alloca un'area di memoria, la lunghezza sarà il prodotto dei suoi parametri. callocriempie la memoria con ZERO e restituisce un puntatore al primo byte. Se non riesce a individuare abbastanza spazio, restituisce un NULLpuntatore.

Sintassi: ptr_var=(cast_type *)calloc(no_of_blocks , size_of_each_block); ieptr_var=(type *)calloc(n,s);

  • malloc()alloca un singolo blocco di memoria di REQUSTED SIZE e restituisce un puntatore al primo byte. Se non riesce a individuare la quantità di memoria richiesta, viene restituito un puntatore null.

Sintassi: ptr_var=(cast_type *)malloc(Size_in_bytes); La malloc()funzione prende un argomento, che è il numero di byte da allocare, mentre la calloc()funzione prende due argomenti, uno è il numero di elementi, e l'altro è il numero di byte da allocare per ciascuno di tali elementi. Inoltre, calloc()inizializza lo spazio allocato a zero, mentre malloc()non lo fa.


6

La calloc()funzione dichiarata <stdlib.h>nell'intestazione offre un paio di vantaggi rispetto alla malloc()funzione.

  1. Alloca memoria come numero di elementi di una determinata dimensione e
  2. Inizializza la memoria allocata in modo che tutti i bit siano zero.

6

malloc() e calloc() sono funzioni della libreria standard C che consentono l'allocazione dinamica della memoria, il che significa che entrambi consentono l'allocazione della memoria durante il runtime.

I loro prototipi sono i seguenti:

void *malloc( size_t n);
void *calloc( size_t n, size_t t)

Ci sono principalmente due differenze tra i due:

  • Comportamento: malloc()alloca un blocco di memoria, senza inizializzarlo, e la lettura del contenuto da questo blocco comporterà valori inutili. calloc()d'altra parte, alloca un blocco di memoria e lo inizializza su zero, e ovviamente la lettura del contenuto di questo blocco comporterà zeri.

  • Sintassi: malloc()accetta 1 argomento (la dimensione da allocare) e calloc()accetta due argomenti (numero di blocchi da allocare e dimensione di ciascun blocco).

Il valore restituito da entrambi è un puntatore al blocco di memoria allocato, se ha esito positivo. In caso contrario, verrà restituito NULL indicando l'errore di allocazione della memoria.

Esempio:

int *arr;

// allocate memory for 10 integers with garbage values
arr = (int *)malloc(10 * sizeof(int)); 

// allocate memory for 10 integers and sets all of them to 0
arr = (int *)calloc(10, sizeof(int));

Le stesse funzionalità calloc()ottenibili utilizzando malloc()e memset():

// allocate memory for 10 integers with garbage values   
arr= (int *)malloc(10 * sizeof(int));
// set all of them to 0
memset(arr, 0, 10 * sizeof(int)); 

Si noti che malloc()è preferibilmente utilizzato calloc()poiché è più veloce. Se si desidera inizializzare zero i valori, utilizzare calloc()invece.


5

Una differenza non ancora menzionata: limite di dimensioni

void *malloc(size_t size)può allocare solo fino a SIZE_MAX.

void *calloc(size_t nmemb, size_t size); può allocare circa SIZE_MAX*SIZE_MAX .

Questa capacità non viene spesso utilizzata in molte piattaforme con indirizzamento lineare. Tali sistemi limitano calloc()con nmemb * size <= SIZE_MAX.

Considera un tipo di 512 byte chiamati disk_sectore il codice vuole usare molti settori. Qui, il codice può usare solo fino a SIZE_MAX/sizeof disk_sectorsettori.

size_t count = SIZE_MAX/sizeof disk_sector;
disk_sector *p = malloc(count * sizeof *p);

Considera quanto segue che consente un'allocazione ancora maggiore.

size_t count = something_in_the_range(SIZE_MAX/sizeof disk_sector + 1, SIZE_MAX)
disk_sector *p = calloc(count, sizeof *p);

Ora, se un tale sistema è in grado di fornire un'allocazione così ampia è un'altra questione. La maggior parte di oggi no. Eppure è successo per molti anni quando SIZE_MAXera 65535. Data la legge di Moore , si sospetta che ciò accadrà intorno al 2030 con alcuni modelli di SIZE_MAX == 4294967295memoria e pool di memoria da 100 GByte.


2
In generale, size_t sarà in grado di contenere le dimensioni del più grande tipo di oggetto che un programma potrebbe gestire. È improbabile che un sistema in cui size_t sia di 32 bit sia in grado di gestire un'allocazione superiore a 4294967295 byte e un sistema in grado di gestire allocazioni di tale dimensione renderebbe quasi sicuramente size_tmaggiore di 32 bit. L'unica domanda è se si possa fare affidamento sull'utilizzo callocdi valori il cui prodotto supera SIZE_MAXper produrre zero anziché restituire un puntatore a un'allocazione più piccola.
supercat

Concordi sulla tua generalizzazione , tuttavia la specifica C consente di calloc()superare le allocazioni SIZE_MAX. È accaduto in passato con 16 bit size_te poiché la memoria continua a indebolirsi, non vedo alcun motivo per cui non potrà succedere anche se non è comune .
chux - Ripristina Monica il

1
Lo standard C consente al codice di richiedere un'allocazione la cui dimensione supera SIZE_MAX. Certamente non richiede l'esistenza di alcuna circostanza in cui tale allocazione potrebbe avere successo; Non sono sicuro che ci sia alcun vantaggio particolare nel richiedere che le implementazioni che non sono in grado di gestire tali allocazioni debbano restituire NULL(soprattutto dato che è comune che alcune implementazioni abbiano mallocpuntatori di ritorno nello spazio non ancora impegnato e potrebbero non essere disponibili quando il codice tenta effettivamente di utilizzare esso).
supercat

Inoltre, laddove in passato potrebbero esserci stati sistemi il cui intervallo di indirizzamento disponibile ha superato il più grande intero rappresentabile, non vedo alcuna possibilità realistica che ciò si verifichi, poiché ciò richiederebbe una capacità di archiviazione di miliardi di gigabyte. Anche se la Legge di Moore continuasse a essere valida, andare dal punto in cui 32 bit cessano di essere sufficienti al punto in cui 64 bit cessano di essere sufficienti richiederebbe il doppio del tempo necessario per arrivare dal punto in cui 16 bit erano sufficienti al punto in cui 32 non era 't.
supercat

1
Perché un'implementazione che può ospitare una dotazione unica di oltre 4G non definire size_ta uint64_t?
supercat

2

Numero di blocchi:
malloc () assegna un singolo blocco della memoria richiesta,
calloc () assegna più blocchi della memoria richiesta

Inizializzazione:
malloc () - non cancella e inizializza la memoria allocata.
calloc () - inizializza la memoria allocata di zero.

Velocità:
malloc () è veloce.
calloc () è più lento di malloc ().

Argomenti e sintassi:
malloc () accetta 1 argomento:

  1. byte

    • Il numero di byte da allocare

calloc () accetta 2 argomenti:

  1. lunghezza

    • il numero di blocchi di memoria da allocare
  2. byte
    • il numero di byte da allocare in ciascun blocco di memoria
void *malloc(size_t bytes);         
void *calloc(size_t length, size_t bytes);      

Modalità di allocazione della memoria:
la funzione malloc assegna la memoria della "dimensione" desiderata dall'heap disponibile.
La funzione calloc assegna una memoria delle dimensioni di "num * size".

Significato sul nome:
il nome malloc significa "allocazione della memoria".
Il nome calloc significa "allocazione contigua".

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.