2013-03-08 18 views
6

Sono nel bel mezzo di un progetto e sto cercando di utilizzare malloc() e realloc(). So quando malloc, funziona, ma quando uso realloc, non cambia affatto la quantità di memoria allocata. Ho sempre pensato che realloc riassegnasse la tua memoria già malleata.La memoria non sta riallocando

Ecco quello che ho:

questo includono:

#include <stdlib.h> 

ho una struct:

struct student { 
    int age; 
    int numOfClasses; 
    int gender; //0 male; 1 female 
} student; 

Quando voglio fare 7 di quei struct usando malloc, lo farò utilizzare questa riga di codice:

student stud* = (structure*) malloc(7*sizeof(student)); 

Questa linea funziona. Quella linea di codice prende la dimensione della struttura e moltiplica quella per 7. In breve, questo prenderà abbastanza memoria per creare una matrice di 7 strutture.

Ora, se voglio cambiare la situazione a 8, farei questo, dove A è il precedente della memoria malloced, e B è il nuovo malloced (o realloced) Memoria:

enter image description here

Ecco come ho in codice:

stud = (student*)realloc(stud, 8*sizeof(student)); 

Da quello che so, realloc prende la variabile nel secondo parametro e mallocs quella quantità di memoria. Quindi, prende il puntatore (o il precedente malloced) e riempie la memoria appena malloced con il maggior numero possibile dal puntatore specificato. Ovviamente, il secondo parametro deve essere più grande della dimensione del malloced precedente oppure stud perderà un po 'di memoria alla fine. Ora questo è il mio problema. Quando chiamo la riga sopra, non cambia nulla. L'array malloced è ancora lungo 7. Sono abbastanza sicuro, anche, di avere abbastanza memoria per realloc.

Sto facendo bene? Dove potrebbe essere il mio problema?

+8

Cosa ti fa pensare che l'array malloced sia ancora di lunghezza 7? –

+0

Questo non si riferisce al tuo problema, ma penso che la tua struttura sia perfetta per un 'enum'. – teppic

risposta

11

La comprensione del comportamento di realloc è quasi corretta. non ha per restituire un puntatore diverso; potrebbe essere che ci fosse abbastanza memoria inutilizzata dopo il blocco iniziale, quindi il gestore dell'heap può semplicemente restituire lo stesso puntatore (ma regolare il proprio stato interno in modo che sappia che il blocco è ora più grande).

Hai fatto un piccolo errore, però.

stud = (student*)realloc(stud, 8*sizeof(student)); 

Qui si sta sostituendo il puntatore stud con il valore restituito da realloc. Se accade di restituire NULL a causa della mancanza di memoria, hai perso il puntatore originale stud e la memoria è trapelata. Dovresti invece utilizzare un puntatore temporaneo.

tmp = realloc(stud, 8*sizeof(student)); 
if (tmp) 
    stud = tmp; 

Inoltre, è ancora necessario inserire qualcosa nell'ottavo slot. Dopo il rialloc l'ottavo slot è una memoria allocata valida, ma contiene spazzatura finché non si memorizza qualcosa di significativo.

+0

Sono abbastanza sicuro che ci sia abbastanza memoria per realloc. –

+1

OK, ma non hai ancora spiegato perché pensi che l'array malloced sia ancora di lunghezza 7. –

+0

Questa è la cosa, non so perché non si assegna dal 7 al 8. –

4

Questo dovrebbe funzionare, anche se mi piacerebbe avere queste raccomandazioni:

Non gettato il ritorno da malloc. È inutile in C e potrebbe nascondere che hai dimenticato di includere <stdlib.h>.

Non utilizzare ptr = realloc (ptr, ...) in quanto ciò crea una perdita di memoria nel caso realloc restituisce NULL. Invece, utilizzare

if ((new_ptr = realloc (stud, 8 * sizeof (*stud))) != NULL) { 
    stud = new_ptr; 
} else { 
    scream_and_die("out of memory"); 
} 

E utilizzare sizeof (*stud), cioè riferimento un'espressione utilizzando il puntatore , non il tipo si punta (per essere indipendente dal particolare tipo di puntatore allocare). In questo modo, quando si rinomina il typedef, la linea malloc/realloc non ha bisogno di modifiche. In altre parole, Best Practice per l'allocazione dinamica della memoria in C è

#include <stdlib.h> 
sometype *ptr; 
... 
ptr = malloc (N * sizeof *ptr); 

per un array di N tipi.

Problemi correlati