Domanda sull'uso dell'implementazione realloc nel codice C ++
-
06-07-2019 - |
Domanda
Amici
Nel nostro C ++, corrente Iam usando il metodo realloc per ridimensionare la memoria allocata da malloc. L'utilizzo di realloc () viene eseguito come di seguito
my_Struct *strPtr =(my_struct*)malloc(sizeof(my_Struct));
/* an later */
strPtr = (my_struct*)realloc(strPtr,sizeof(my_Struct)*NBR);
ora wikipeadia (_http: //en.wikipedia.org/wiki/Malloc) dice che
Se invece lo ha fatto
void *p = malloc(orig_size);
/* and later... */
p = realloc(p, big_size);
quindi nel caso in cui non sia possibile ottenere byte di memoria big_size, p avrà valore NULL e non avremo più un puntatore alla memoria precedentemente allocata per p, creando una perdita di memoria
E dice anche che il modo corretto per correggere l'errore sopra è
void *p = malloc(orig_size);
/* and later... */
void *tmp = realloc(p, big_size);
if (tmp != NULL)
{
p = tmp; /* OK, assign new, larger storage to p */
}
else
{
/* handle the problem somehow */
}
Puoi dirmi qual è il modo migliore per usare realloc ()
anche una volta ho il puntatore a una struttura e poi, usando Realloc in seguito, posso usare il puntatore a un vuoto ???
Molte grazie
Soluzione
Ovviamente devi proteggerti dal caso in cui realloc()
restituisca NULL
. È un'allocazione di memoria, e in C (dove <=>) è principalmente usato, penso che i programmatori C ++ ritengano che sia un po 'di basso livello / qaint usare chiamate <=> non elaborate, le allocazioni di memoria possono sempre fallire.
La sovrascrittura diretta del puntatore con il valore restituito è un errore, in quanto rilascia il puntatore originale e fa perdere la memoria nel caso in cui la riallocazione fallisca.
Altri suggerimenti
Malloc () e realloc () sono funzioni C. In realtà, realloc () fa malloc () e free () a seconda degli argomenti passati:
- Se gli passi un puntatore null, realloc fa quello che fa malloc.
- Se gli passi una dimensione zero, realloc fa ciò che fa gratuitamente.
Citato da Qui , dove hai una spiegazione più approfondita.
La libreria C rende impossibile espandere un blocco di memoria in posizione, quindi C ++ non lo supporta neanche.
Se si desidera attenersi alle funzioni C, è necessario tenere il puntatore della prima allocazione di memoria quando si chiama realloc (). Quindi controlla se è NULL, altrimenti lo assegni, proprio come hai fatto nel tuo codice latst.
Ma forse per C ++ la soluzione migliore è quella di creare il proprio mallocator, la soluzione std basata sul C malloc (). Controlla questo o questo .
Usa l'approccio suggerito & # 8211; tenere il puntatore al buffer precedente fino a quando realloc non è tornato correttamente. Una volta che realloc () restituisce correttamente il blocco precedente è stato liberato e tutti i puntatori ad esso sono diventati penzolanti & # 8211; adattali.
a realloc e a malloc non importa quale sia il tipo di puntatore: puoi usare void * e qualsiasi altra cosa *.
Come altri hanno già detto, basta usare realloc correttamente come suggerito.
Ma il " C ++ way " di fare questo è davvero usare uno std :: vector < > piuttosto che mantenere gli array da soli. In questo modo la libreria standard C ++ si occuperà dei dettagli di basso livello della riallocazione (presumibilmente usando realloc ()).
Quando realloc () fallisce e restituisce NULL, la memoria originale non viene toccata.
Quindi dovresti usarlo in questo modo:
my_Struct* strPtr =(my_struct*)malloc(sizeof(my_Struct));
/* an later */
my_Struct* tmp = (my_struct*)realloc(strPtr,sizeof(my_Struct)*NBR);
if (tmp != NULL)
{
strPtr = tmp;
}
else
{
/* realloc Failed. Need to do something */
}
Perché stai usando malloc e realloc? C'è quasi sempre un modo migliore in C ++.
Se lo stai usando per creare matrici di lunghezza variabile, stai quasi sicuramente meglio con std :: vector < > ;, o forse uno degli altri modelli di container.
Se invece usi C, forse con un compilatore con capacità C ++, il modo corretto è il secondo metodo, che non perde un intero blocco di memoria quando non riesce a allocare.
La risposta alla tua seconda domanda dipende anche se stai usando C o C ++. In C, void * è un tipo di puntatore di dati generico ed è liberamente convertibile. In C ++, void * deve essere esplicitamente convertito. Se stai effettivamente scrivendo C, devi usare malloc () e amici, che funzionano su void *. Se stai davvero scrivendo C ++, devi lanciare, il che lo rende più imbarazzante. In nessun caso realloc () funziona con i puntatori a struct, ma piuttosto con i puntatori a void.