b'\n_START_ARTICLE_\nMalloc\n_START_PARAGRAPH_\nIn informatica, malloc (derivato dai termini memory allocation) \xc3\xa8 una funzione della libreria standard dei linguaggi di programmazione C e C++ per l\'allocazione dinamica della memoria.\n_START_SECTION_\nConcetti\n_START_PARAGRAPH_\nNel linguaggio di programmazione C la memoria pu\xc3\xb2 essere gestita staticamente, automaticamente o dinamicamente. Nella gestione statica le variabili sono allocate in una posizione fissa che persiste fino alla fine del programma; in quella automatica sono allocate nello stack e vengono inserite e rimosse in funzione delle chiamate e dei ritorni di funzione. Nell\'allocazione automatica la dimensione \xc3\xa8 richiesta durante il periodo di compilazione come costante. Se la dimensione non \xc3\xa8 nota durante il periodo di esecuzione (per esempio, se i dati devono essere inseriti via via da tastiera), questo metodo diventa inadeguato._NEWLINE_La durata dell\'allocazione della memoria \xc3\xa8 un\'altra fonte di preoccupazione. N\xc3\xa9 l\'allocazione statica n\xc3\xa9 quella automatica sono sufficienti per tutte le situazioni. In quella automatica i dati possono non persistere per pi\xc3\xb9 chiamate di funzione, mentre quella statica persiste per tutta la durata del programma sia nel caso in cui sia necessaria, sia in quello in cui non sia pi\xc3\xb9 utile. In molte situazioni il programmatore necessita di una maggiore flessibilit\xc3\xa0 nella gestione del ciclo di vita della memoria allocata._NEWLINE_Queste limitazioni sono evitabili utilizzando l\'allocazione dinamica della memoria, la quale \xc3\xa8 pi\xc3\xb9 esplicita (ma pi\xc3\xb9 flessibile), ed \xc3\xa8 gestita, in genere, mediante l\'allocazione nell\'heap. Il programma accede a questo blocco di memoria tramite un puntatore che la malloc restituisce. Quando non \xc3\xa8 pi\xc3\xb9 necessaria, la memoria pu\xc3\xb2 essere deallocata tramite la funzione free() in modo che possa essere utilizzata per altri scopi._NEWLINE_Alcune piattaforme forniscono delle chiamate alla libreria che permettono l\'allocazione dinamica in run-time (durante l\'esecuzione del programma) dallo stack piuttosto che dall\'heap (per esempio glibc\'s alloca(), Microsoft Windows CRTL\'s malloca()). Questa memoria viene liberata al termine della chiamata. La loro necessit\xc3\xa0 \xc3\xa8 stata attenuata dai cambiamenti apportati nella C99, che ha aggiunto il supporto per gli array a lunghezza variabile nel blocco di scope aventi dimensioni determinate in run-time.\n_START_SECTION_\nAllocazione dinamica della memoria in C\n_START_PARAGRAPH_\nLa funzione malloc \xc3\xa8 una di quelle appartenenti allo standard C per l\'allocazione della memoria. Il suo prototipo \xc3\xa8_NEWLINE_void *malloc(size_t size);_NEWLINE_Che alloca size byte di memoria. Se l\'operazione ha successo, viene restituito un puntatore al blocco di memoria, mentre in caso contrario verr\xc3\xa0 restituito un puntatore null._NEWLINE_In caso di successo, malloc restituisce un puntatore void (void *) che indica che si tratta di un puntatore ad una regione di dati di tipo sconosciuto. Non deve essere espresso in modo esplicito ad un puntatore di tipo specifico, poich\xc3\xa9 l\'ANSI C definisce una conversione implicita tra il void ed altri tipi. Un cast esplicito \xc3\xa8 a volte presente poich\xc3\xa9 originariamente veniva restituito un char *, ma questo non \xc3\xa8 necessario nello standard C. La sua omissione causa tuttavia una incompatibilit\xc3\xa0 con il C++, che lo richiede._NEWLINE_La memoria allocata tramite malloc \xc3\xa8 persistente: ci\xc3\xb2 significa che continuer\xc3\xa0 ad esistere fino alla fine del programma o fino a quando non sar\xc3\xa0 esplicitamente deallocata dal programmatore (detto anche "liberata"). Questo risultato \xc3\xa8 ottenuto tramite la funzione free. Il suo prototipo \xc3\xa8_NEWLINE_void free(void* pointer);_NEWLINE_Che rilascia il blocco di memoria indicato da pointer.  pointer deve essere stato precedentemente allocato con malloc, calloc o realloc e deve essere passato una sola volta tramite free.\n_START_SECTION_\nEsempi di utilizzo\n_START_PARAGRAPH_\nIl metodo standard per creare un array di dieci interi:_NEWLINE_int array[10];_NEWLINE_Tuttavia, se si vuole assegnare un simile array in modo dinamico, si pu\xc3\xb2 utilizzare il seguente codice:_NEWLINE_/* Alloca spazio per un array con 10 elementi di tipo int. */int *ptr = (int *)malloc(10 * sizeof (int));if (!ptr) _NEWLINE_{_NEWLINE_    /* La memoria non pu\xc3\xb2 essere allocata, il programma dovrebbe gestire l\'errore in modo appropriato. */} else _NEWLINE_{_NEWLINE_    /* Allocazione avvenuta con successo.  Prosegui con il programma.  */_NEWLINE_    free(ptr);  /* Abbiamo finito di lavorare con l\'array, e liberiamo il puntatore associato. */ _NEWLINE_    ptr = NULL; /* Il puntatore non pu\xc3\xb2 essere pi\xc3\xb9 usato fino ad un riassegnamento effettuato con malloc. */}_NEWLINE_malloc restituisce un puntatore nullo per indicare che la memoria non \xc3\xa8 disponibile o che qualche altro errore gli ha impedito di allocarla._NEWLINE_Si pu\xc3\xb2 notare che a volte il codice restituito da malloc ha un "cast" ad uno specifico tipo, come in_NEWLINE_int *ptr = (int*)malloc(10 * sizeof (int));_NEWLINE_Ma questa \xc3\xa8 una cattiva pratica: \xc3\xa8 ridondante sotto lo standard C, come osservato in precedenza; e inoltre, il cast maschera l\'eventuale mancata inclusione dell\'header stdlib.h, che contiene il prototipo della malloc. In assenza del prototipo per malloc, il compilatore C assumer\xc3\xa0 che malloc restituisce un int, e mander\xc3\xa0 un avviso per indicare che la condizione dell\'errore non sar\xc3\xa0 mascherata dal cast (avvisa quindi di non preoccuparsi perch\xc3\xa9 sa come gestire la situazione)_NEWLINE_Un utile idioma con la malloc \xc3\xa8 illustrato in questo esempio:_NEWLINE_int *ptr = malloc(10 * sizeof (*ptr));_NEWLINE_Ci\xc3\xb2 significa che, invece di scrivere un tipo hard-wired all\'interno dell\'argomento della malloc, usa un operatore sizeof sul contenuto del puntatore per l\'assegnazione. Questo fa in modo che in caso di cambiamenti apportati durante una revisione del codice, i tipi a destra e a sinistra saranno sempre sincronizzati.\n_START_SECTION_\nCalloc\n_START_PARAGRAPH_\nmalloc restituisce un blocco di memoria allocato dal programmatore per essere utilizzato, ma non \xc3\xa8 inizializzato. Questa operazione \xc3\xa8 spesso effettuata a mano, se necessario, tramite la funzione memset, o da una o pi\xc3\xb9 assegnazioni con dereferenziazione del puntatore. Un\'alternativa \xc3\xa8 di usare la funzione calloc, che alloca la memoria e la inizializza. Il prototipo \xc3\xa8_NEWLINE_void *calloc(size_t nelements, size_t elementSize);_NEWLINE_che alloca un\'area di memoria, la inizializza a 0, di dimensioni nelements\xc2\xa0\xc3\x97\xc2\xa0elementSize.\n_START_SECTION_\nRealloc\n_START_PARAGRAPH_\nSpesso \xc3\xa8 utile che un blocco di memoria possa crescere o ridursi. Questo pu\xc3\xb2 essere fatto utilizzando realloc che restituisce un puntatore ad una zona di memoria di una specifica dimensione, che contiene gli stessi dati della vecchia regione indirizzata da pointer (troncata alla fine nel caso la nuova dimensione sia minore di quella precedente). Se realloc non \xc3\xa8 in grado di ridimensionare l\'array sul posto, allocher\xc3\xa0 una nuova area delle nuove dimensioni, copier\xc3\xa0 i dati richiesti, e liberer\xc3\xa0 il vecchio puntatore. Se l\'allocazione fallisce, realloc mantiene il puntatore originale inalterato e restituisce un puntatore vuoto. La nuova area di memoria non \xc3\xa8 inizializzata (il suo contenuto non \xc3\xa8 prevedibile). Il prototipo della funzione \xc3\xa8_NEWLINE_void *realloc(void *pointer, size_t size);_NEWLINE_la funzione realloc si comporta come malloc se il primo argomento \xc3\xa8 NULL:_NEWLINE_void *p = malloc(42);void *p = realloc(NULL, 42); /* equivalent */_NEWLINE_Nello standard C89, realloc con dimensione 0 era uguale ad una chiamata a free(). Nello standard C99, non \xc3\xa8 stata mantenuta questa possibilit\xc3\xa0; ora, il blocco viene riallocato con una dimensione di zero byte ed \xc3\xa8 restituito un puntatore diverso da null (che non pu\xc3\xb2 essere direttamente dereferenziato, dato che non punta a nessuna area di memoria allocata, ma potr\xc3\xa0 essere usata per una futura chiamata a realloc o free)._NEWLINE_Si deve sempre utilizzare una variabile temporanea. Ad esempio:_NEWLINE_void *p = malloc(orig_size);/* e dopo... */void *tmp = realloc(p, big_size); _NEWLINE_if (tmp != NULL) {_NEWLINE_   p = tmp; /* OK, nuovo assegnamento, pi\xc3\xb9 grande di p */} else {_NEWLINE_   /* gestire il problema in qualche modo */}_NEWLINE_Se invece uno ha_NEWLINE_void *p = malloc(orig_size);/* e dopo... */p = realloc(p, big_size);_NEWLINE_nel caso in cui non sia possibile ottenere big_size byte di memoria, p avr\xc3\xa0 un valore null e nessun puntatore all\'area di memoria precedentemente allocata per p, creando un memory leak.\n_START_SECTION_\nErrori comuni\n_START_PARAGRAPH_\nL\'uso improprio della malloc e delle relative funzioni pu\xc3\xb2 essere frequentemente fonte di problemi.\n_START_SECTION_\nAllocazione fallita\n_START_PARAGRAPH_\nmalloc non garantisce il successo dell\'operazione, e se non c\'\xc3\xa8 memoria disponibile, o se il programma ha superato il limite di memoria che pu\xc3\xb2 referenziare, malloc restituir\xc3\xa0 un puntatore null. Molti programmi non controllano questa eventualit\xc3\xa0. Se il programma tenter\xc3\xa0 di utilizzare il puntatore null restituito dalla malloc come se fosse un normale puntatore ad un\'area di memoria allocata, il programma andr\xc3\xa0 in crash.\n_START_SECTION_\nMemory leak\n_START_PARAGRAPH_\nQuando chiami una malloc, una calloc o una realloc con successo, il valore restituito dalla chiamata pu\xc3\xb2 eventualmente essere fatto passare per la funzione free. Questo rilascer\xc3\xa0 la memoria allocata, per permetterle di essere riutilizzata per altri scopi. Se questo non avviene, la memoria allocata non verr\xc3\xa0 liberata fino alla fine del processo; in altre parole, si former\xc3\xa0 un memory leak. Tipicamente, un memory leak \xc3\xa8 causato dalla perdita di un puntatore, per esempio non utilizzando un puntatore temporaneo durante una chiamata alla realloc, che pu\xc3\xb2 portare la sovrascrittura del puntatore originale con un puntatore null, per esempio:_NEWLINE_void *ptr;size_t size = BUFSIZ;_NEWLINE_ _NEWLINE_ptr = malloc(size);_NEWLINE_ _NEWLINE_/* qui avvengono ulteriori operazioni... */_NEWLINE_ _NEWLINE_/* ora la dimensione del buffer deve essere raddoppiata */if (size > SIZE_MAX / 2) {_NEWLINE_  /* errore di overflow */_NEWLINE_  /* ... */_NEWLINE_  return (1);}size *= 2;ptr = realloc(ptr, size);if (ptr == NULL) {_NEWLINE_  /* la realloc fallisce (e restituisce un puntatore null), ma il puntatore originale ptr \xc3\xa8 andato perduto      quindi la memoria non pu\xc3\xb2 essere liberata e avviene una perdita di memoria */_NEWLINE_  /* ... */_NEWLINE_  return 1;}/* ... */\n_START_SECTION_\nUtilizzo dopo free()\n_START_PARAGRAPH_\nDopo che un puntatore \xc3\xa8 passato per una funzione free, il puntatore referenzia una regione di memoria, con indefinito contenuto, che non pu\xc3\xb2 essere utilizzata. Non si pu\xc3\xb2 accedere al contenuto del puntatore. Per esempio:_NEWLINE_int *ptr = (int*)malloc(sizeof (int));free(ptr);*ptr = 0; /* comportamento indefinito */_NEWLINE_Il codice avr\xc3\xa0 un comportamento i cui effetti possono variare. Anche il tentativo di stampare la variabile printf ha un effetto indefinito (assumendo che malloc non restituisca un puntatore null); per esempio:_NEWLINE_printf("%p", (void *) ptr); /* comportamento indefinito */_NEWLINE_Comunemente, il sistema pu\xc3\xb2 riutilizzare la memoria liberata per altri scopi. Pertanto, la scrittura in memoria verso un puntatore ad una regione deallocata, pu\xc3\xb2 avere come risultato una sovrascrittura di altri dati del programma stesso. A seconda del tipo di dati che vengono sovrascritti, questo pu\xc3\xb2 causare la corruzione dei dati stessi e un successivo crash del programma. Un cattivo esempio del tentativo di risolvere questo problema pu\xc3\xb2 essere il doppio passaggio tramite free, conosciuto come doppia liberazione. Per evitare questo, alcuni programmatori settano a NULL il puntatore dopo il passaggio per free: _NEWLINE_free(ptr);ptr = NULL; /*\xc3\xa8 sicuro (butta via la locazione del puntatore).*/_NEWLINE_Questa funzione \xc3\xa8 sicura e non provoca anomalie, tuttavia, anche questo accorgimento non riesce a proteggere da altri usi impropri dello stesso puntatore doppiamente liberato._NEWLINE_La prassi migliore \xc3\xa8 quella di passare fuori dallo scope (o visibilit\xc3\xa0) immediatamente dopo aver liberato la memoria.\n_START_SECTION_\nLiberare memoria non allocata\n_START_PARAGRAPH_\nUn altro problema pu\xc3\xb2 sopraggiungere passando un puntatore a free quando per\xc3\xb2 non \xc3\xa8 stato precedentemente allocato con malloc, realloc o calloc.  Il comportamento anomalo pu\xc3\xb2 essere causato quando un puntatore ad una stringa o ad un array, dichiarato in modo statico, \xc3\xa8 passato con la funzione free, per esempio:_NEWLINE_char *msg = "Messaggio predefinito";int tbl[100];_NEWLINE_Il passaggio di entrambi i puntatori a free restituir\xc3\xa0 comunque un comportamento indefinito.\n_START_SECTION_\nLimite spazio di allocazione\n_START_PARAGRAPH_\nIl blocco di memoria pi\xc3\xb9 grande possibile che malloc pu\xc3\xb2 allocare dipende dal sistema sottostante, in particolare dalla memoria fisica e dall\'implementazione nel sistema operativo. Teoricamente, il pi\xc3\xb9 grande numero dovrebbe essere il valore massimo che pu\xc3\xb2 essere contenuto in un tipo size t, ossia una implementazione dipendente di intero senza segno che rappresenta la dimensione dello spazio di memoria. Il valore massimo \xc3\xa8 2 \xe2\x88\x92 1, o la costante SIZE_MAX nello standard C99.'