2010-04-30 20 views
16

Sono un po 'nuovo a malloc e C in generale. Volevo sapere come posso, se necessario, estendere le dimensioni di un array con dimensioni fisse altrimenti con malloc.C: Espansione di un array con malloc

Esempio:

#define SIZE 1000 
struct mystruct 
{ 
    int a; 
    int b; 
    char c; 
}; 
mystruct myarray[ SIZE ]; 
int myarrayMaxSize = SIZE; 
.... 
if (i > myarrayMaxSize) 
{ 
    // malloc another SIZE (1000) elements 
    myarrayMaxSize += SIZE; 
} 
  • L'esempio di cui sopra dovrebbe rendere chiaro quello che voglio realizzare.

(A proposito: ho bisogno di questo per un interprete scrivo: Lavorare con un importo fisso di variabili e, in caso di più sono necessari, basta allocare dinamicamente)

risposta

15

Usa realloc, ma bisogna allocare prima l'array con malloc. Lo stai allocando in pila nell'esempio sopra.

size_t myarray_size = 1000; 
    mystruct* myarray = malloc(myarray_size * sizeof(mystruct)); 

    myarray_size += 1000; 
    mystruct* myrealloced_array = realloc(myarray, myarray_size * sizeof(mystruct)); 
    if (myrealloced_array) { 
    myarray = myrealloced_array; 
    } else { 
    // deal with realloc failing because memory could not be allocated. 
    } 
+5

'x = realloc (x, newsize)' è una perdita di memoria in attesa di accadere. –

+0

Buon punto. Ho aggiornato il codice di esempio per gestire gli errori realloc. –

+0

'myarray = myrealloced_array)' dovrebbe essere 'myarray = myrealloced_array;' :) – Saul

6

No, non è possibile. Non è possibile modificare la dimensione di un array nello stack una volta definito: questo è il tipo di cosa significa dimensioni fisse. Oppure un array globale: non è chiaro dal tuo esempio di codice in cui è definito myarray.

Si potrebbe malloc una matrice di 1000 elementi e successivamente ridimensionarla con realloc. Questo può restituirti un nuovo array, contenente una copia dei dati da quello vecchio, ma con uno spazio extra alla fine.

1

a) non è stato utilizzato malloc per crearlo in modo da non espandersi con malloc. Do:

mystruct *myarray = (mystruct*)malloc(sizeof(mystruct) *SIZE); 

b) utilizzare realloc (RTM) per renderlo più grande

+1

RTM -> http://www.cplusplus.com/reference/cstdlib/realloc/ – Mawg

12

Volete usare realloc (come altri utenti hanno già fatto notare). Ma, purtroppo, gli altri utenti hanno non è dimostrato come usare correttamente:

POINTER *tmp_ptr = realloc(orig_ptr, new_size); 
if (tmp_ptr == NULL) 
{ 
    // realloc failed, orig_ptr still valid so you can clean up 
} 
else 
{ 
    // Only overwrite orig_ptr once you know the call was successful 
    orig_ptr = tmp_ptr; 
} 

è necessario utilizzare tmp_ptr in modo che se realloc fallisce, non si perde il puntatore originale.