2011-11-29 15 views
5

È davvero un post per qualche consiglio in termini di utilizzo di realloc, in particolare, se potessi utilizzarlo per semplificare il mio codice esistente. In sostanza, ciò che segue fa allocare dinamicamente un po 'di memoria, se passo oltre 256, quindi l'array deve essere aumentato di dimensioni, così ho malloc un array temporaneo, con 2x la dimensione, memcpy ecc. (Vedi sotto).Utilizzo di Realloc in C

Mi chiedevo solo se realloc potesse essere utilizzato nel codice sottostante, per semplificarlo, qualsiasi consiglio, codice di esempio o anche suggerimenti su come implementarlo è molto apprezzato!

Cheers.

void reverse(char *s) { 
char p; 

switch(toupper(s[0])) 
{ 
    case 'A': case 'E': case 'I': case 'O': case 'U': 
     p = s[strlen(s)-1]; 
     while(p >= s) 
      putchar(p--); 
     putchar('\n'); 
     break; 
    default: 
     printf("%s", s); 
     break; 
} 
printf("\n"); 
    } 

    int main(void) { 
char c; 
int buffer_size = 256; 
char *buffer, *temp; 
int i=0; 

buffer = (char*)malloc(buffer_size); 
while (c=getchar(), c!=' ' && c!='\n' && c !='\t') 
{ 
    buffer[i++] = c; 
    if (i >= buffer_size) 
    { 
     temp = (char*)malloc(buffer_size*2); 
     memcpy(temp, buffer, buffer_size); 
     free(buffer); 
     buffer_size *= 2; 
     buffer = temp; 
    } 
} 
buffer[i] = '\0'; 
reverse(buffer); 

return 0; 

}

+1

Una nota di stile: si dovrebbe preferire ** non ** a trasmettere il valore restituito di 'malloc'. –

+1

E 'reverse' dovrebbe prendere l'argomento come' const char * '. –

risposta

11

è la risposta breve. Ecco come dovrebbe apparire:

if (i >= buffer_size) 
{ 
    temp = realloc(buffer, buffer_size*2); 
    if (!temp) 
     reportError(); 
    buffer_size *= 2; 
    buffer = temp; 
} 

Si noti che è comunque necessario utilizzare un puntatore temporanea per contenere il risultato di realloc(); se l'allocazione fallisce, hai ancora il puntatore buffer originale al buffer esistente ancora valido.

1

Realloc è più o meno esattamente quello che stai cercando - è possibile sostituire quello intero isolato all'interno del if (i >= buffer_size) con qualcosa di simile:

buffer = (char*)realloc(buffer, buffer_size*2); 
buffer_size *= 2; 

Si noti che questo ignora l'errore condizione (se il ritorno da realloc è NULL); cogliere questa condizione è lasciata al lettore.

1

Sì, realloc può essere utilizzato per semplificare leggermente il codice. Se non sei interessato a di gestione degli errori, allora questo:

char *tmp = malloc(size*2); 
memcpy(temp, buffer, size); 
free(buffer); 
buffer = tmp; 

è sostanzialmente equivalente a questo:

buffer = realloc(buffer, size*2); 

Se siete interessati a gestione degli errori (e probabilmente dovrebbe essere), quindi sarà necessario verificare i valori di ritorno NULL. Questo vale anche per il tuo codice originale.

+1

-1. se il realloc fallisce (restituendo NULL), hai perso il riferimento al blocco originale. –

+1

@Graham: ho detto esplicitamente "se non ti interessa la gestione degli errori". L'OP non ha alcuna gestione degli errori nel suo codice originale, neanche. –

+1

Questa "gestione degli errori" non è solo un gioco da ragazzi come il controllo di 'std :: cin >> n'; questo qui potrebbe e causerà quasi sicuramente UB ... –

1

Sì, per semplificare il codice, è possibile sostituire

if (i >= buffer_size) 
{ 
    temp = (char*)malloc(buffer_size*2); 
    memcpy(temp, buffer, buffer_size); 
    free(buffer); 
    buffer_size *= 2; 
    buffer = temp; 
} 

con

if (i >= buffer_size) 
    buffer = realloc(buffer, buffer_size *= 2); 

Questo non prende in considerazione il controllo degli errori, quindi è necessario verificare che realloc doesn' t restituire NULL.

+1

'realloc' potrebbe restituire' NULL', dando una perdita irreversibile istantanea. –

+2

-1.se il realloc fallisce (restituendo NULL), hai perso il riferimento al blocco originale. –

+2

@GrahamBorland Ho detto che potresti sostituire il suo codice originale con quel codice. Non ha controllato "NULL", quindi neanche io. Ma ho aggiunto una nota per dirlo. –