[C] dubbi su differenza malloc e realloc
#include <stdio.h> #include <stdlib.h> int main() { int *v=NULL ; int i, val; int size = 0; do { printf ( "Inserire un nuovo elemento nell'array :"); scanf ("%d", &val); v = (int*) realloc( v, (++size)*(sizeof(int)) ); v[size-1] = val; // ????????????????????? } while (val != -1); printf( "Elementi nell'array:"); for ( i=0; i < size; i++ ) printf ("%d ", v[i]); free(v); return 0; }
Qualcuno potrebbe spiegarmi l'istruzione dove ho messo i punti di domanda? Se while (val ?= -1) mi permette di bloccare il ciclo digitando -1, allora non capisco a cosa serve l'istruzione v[size-1]=val. Modificando in entrambe le istruzioni -1 con -2 ,il ciclo non dovrebbe avere lo stesso output ma bloccarsi con -2? Infine non mi è' chiara la differenza tra mallocdebug e realloc.. nel mio libro di testo e' stato dato come esercizio chiarificatore sulla malloc la " costruzione "di una qualsiasi matrice dinamica. L'esercizio l'ho svolto e funziona perfettamente ma a questo punto non capisco il motivo per cui in questo esempio non poteva essere usata l'istruzione malloc per allocare la variabile sizeof. Per sizeof infatti , tanto quando oer una matrice dinamica , variabile dim , io non so a priori lo spazio che sarà necessaria allocare.. Grazie mille a tutti coloro che avranno la pazienza di rispondere alle mie domande
Risposte
In "val" l'utente inserisce il nuovo valore da inserire nell'array. while (val != -1) significa semplicemente che quando l'utente inserisce -1, vuole comunicare che ha finito di inserire elementi nell'array. Non è legato a v[size - 1].
v[size - 1] è l'ultimo elemento dell'array (gli indici vanno da 0 a n-1). Quindi v[size - 1] = val, assegna val all'ultima posizione dell'array.
Se cambi -1 in -2 nel while, ottieni che il ciclo di inserimento si ferma quando l'utente inserisce -2. Ma in v[size - 1] devi lasciare -1.
L'ultima domanda non mi è chiarissima. Cos'è mallocdebug (intendi semplicemente malloc?)? realloc può essere vista come una combinazione di malloc + memcpy + free. Se vuoi allungare un array dinamico, devi prima crearne uno più lungo, copiare il contenuto del primo nel secondo, e chiamare free sul primo. realloc fa tutto questo (a meno che il primo array sia già lungo abbastanza, nel caso non fa niente).
sizeof non è una variabile, ma è un operatore eseguito durante la compilazione (non durante l'esecuzione). sizeof(T) Indica la dimensione in char del tipo T. sizeof var indica la dimensione in char della variabile var. char è "l'unità di misura", è il più piccolo tipo di dato possibile (sizeof(char) = 1 sempre).
malloc e realloc prendono in ingresso la dimensione della memoria da allocare in char. Ma per allocare spazio per 3 int devi sapere quanti char è grosso un int, quindi allochi spazio per 3*sizeof(int) char. A seconda delle implementazioni, sizeof(int) può essere 1, 2, 4...
v[size - 1] è l'ultimo elemento dell'array (gli indici vanno da 0 a n-1). Quindi v[size - 1] = val, assegna val all'ultima posizione dell'array.
Se cambi -1 in -2 nel while, ottieni che il ciclo di inserimento si ferma quando l'utente inserisce -2. Ma in v[size - 1] devi lasciare -1.
L'ultima domanda non mi è chiarissima. Cos'è mallocdebug (intendi semplicemente malloc?)? realloc può essere vista come una combinazione di malloc + memcpy + free. Se vuoi allungare un array dinamico, devi prima crearne uno più lungo, copiare il contenuto del primo nel secondo, e chiamare free sul primo. realloc fa tutto questo (a meno che il primo array sia già lungo abbastanza, nel caso non fa niente).
sizeof non è una variabile, ma è un operatore eseguito durante la compilazione (non durante l'esecuzione). sizeof(T) Indica la dimensione in char del tipo T. sizeof var indica la dimensione in char della variabile var. char è "l'unità di misura", è il più piccolo tipo di dato possibile (sizeof(char) = 1 sempre).
malloc e realloc prendono in ingresso la dimensione della memoria da allocare in char. Ma per allocare spazio per 3 int devi sapere quanti char è grosso un int, quindi allochi spazio per 3*sizeof(int) char. A seconda delle implementazioni, sizeof(int) può essere 1, 2, 4...
Per gli array in realtà esiste anche calloc.
Quel codice comunque è pensato male: nessuno sano di mente allocherebbe e riallocherebbe cosi spesso. In genere si alloca più spazio di quanto è necessario e si va avanti fino a riempirlo per poi riallocarne un bel po' di più. Avendo scopi educativi penso che dia l'impressione, sbagliata, che riallocare un array sia una operazione a costo quasi 0. Avrebbe avuto più senso se avesse riallocato ogni n elementi (se non in modo esponenziale come in vector del C++).
Quel codice comunque è pensato male: nessuno sano di mente allocherebbe e riallocherebbe cosi spesso. In genere si alloca più spazio di quanto è necessario e si va avanti fino a riempirlo per poi riallocarne un bel po' di più. Avendo scopi educativi penso che dia l'impressione, sbagliata, che riallocare un array sia una operazione a costo quasi 0. Avrebbe avuto più senso se avesse riallocato ogni n elementi (se non in modo esponenziale come in vector del C++).