Sostituzione di realloc (C -> C ++)

In una domanda precedente, ho chiesto informazioni sui puntatori di typecasting, ma sono stato indirizzato alla soluzione migliore dell’utilizzo del sistema di allocazione C ++ invece dei mallocs. (Sto convertendo un codice C in C ++)

Tuttavia, ho ancora un problema con una funzione simile:

Ho cambiato:

tmp = malloc(sizeof(char*) * mtmp); --> tmp = new char*[mtmp]; 

e

 free(tmp) --> delete [] tmp; 

Tuttavia, cosa devo fare con realloc nella seguente funzione:

 char* space_getRndPlanet (void) { int i,j; char **tmp; int ntmp; int mtmp; char *res; ntmp = 0; mtmp = CHUNK_SIZE; //tmp = malloc(sizeof(char*) * mtmp); <-- replaced with line below tmp = new char*[mtmp]; for (i=0; i<systems_nstack; i++) for (j=0; jreal == ASSET_REAL) { ntmp++; if (ntmp > mtmp) { /* need more space */ mtmp += CHUNK_SIZE; tmp = realloc(tmp, sizeof(char*) * mtmp); name; 

Sto ottenendo il seguente errore:

 error: invalid conversion from 'void*' to 'char**'| 

MODIFICA 2:

Ok, il consenso che sto ottenendo è che dovrei abbandonare la mia attuale soluzione (che sono aperto a fare).

Giusto per assicurarmi che io stia capendo correttamente, voi ragazzi intendete dire che, invece di una serie di puntatori agli oggetti, dovrei semplicemente avere un vettore contenente gli oggetti stessi?

C consente a void* di essere convertito implicitamente a qualsiasi puntatore. C ++ no, quindi se stai usando realloc , devi realloc il risultato al tipo appropriato.

Ma ancora più importante, l’uso di realloc su un puntatore restituito da new[] è un comportamento indefinito. E non esiste uno stile C ++ diretto equivalente a realloc .

Le tue scelte sono, dal meno al più idiomatico:

  • Attenersi a malloc / realloc / free e lanciare i puntatori.
  • Utilizza new[] + delete[] invece di realloc
  • Usa std::vector invece di gestire la tua memoria.

Questo sembra essere un array insignificante che cresce all’occorrenza.

Smetti di usare l’allocazione esplicita della memoria, quasi certamente non ne hai bisogno. Usa std::vector o un altro contenitore dinamico della libreria standard C ++ che cresce automaticamente secondo le tue necessità.

Sembra anche che tu stia usando stringhe in stile C con terminazione nulla. Perché non usare std::string invece?

In C ++ non dovresti usare array (anche allocati dynamicmente).

Questo è stato sostituito con std :: vector

In C:

 char** tmp = (char**)malloc(sizeof(char*) * size); free(tmp); // And a correct version of realloc char** alt = (char**)realloc(sizeof(char*) * newSize); if (alt) { // Note if realloc() fails then it returns NULL // But that does not mean the original object is deallocated. tmp = alt; } 

In C ++

 std::vector tmp(size); // No need for free (destructor does that). tmp.resize(newSize); 

http://www.cplusplus.com/forum/general/18311/

(In breve – non c’è davvero un equivalente in C ++ per realloc , ma forse sarebbe meglio usare un vector ?)

Realloc non si preoccupa davvero di chiamare i costruttori, quindi l’uso di realloc dopo il nuovo sembra una ctriggers idea. Dovresti optare per il vettore come approccio migliore. È ansible ridimensionare i vettori.

Sfortunatamente non c’è un realloc in C ++ (dovuto al fatto che la memoria potrebbe contenere oggetti non banali o solo non copiabili). Assegna un nuovo buffer e copia o impara a usare std::vector o std::stack che lo farebbe automaticamente.

Prenderò in considerazione il passaggio dall’array dinamico a un vettore a una buona scelta.

Per quanto riguarda la possibilità che il vettore contenga oggetti direttamente o contenga puntatori agli oggetti reali, non esiste un’unica risposta definitiva, dipende da un numero di fattori.

L’unico grande fattore è se questi sono quelli che definirei oggetti ” quadro”, quelli per cui la copiatura non ha senso. Un classico caso in questione sarebbe qualcosa come un iostream o una connessione di rete. In genere non esiste un modo logico per copiare o assegnare un object come questo. Se questo è il tipo di object con cui hai a che fare, sei praticamente bloccato nei puntatori.

Se, tuttavia, hai a che fare con ciò che generalmente (in modo approssimativo) definito come “oggetti valore”, la copia e l’assegnazione andranno bene, e la memorizzazione degli oggetti direttamente nel vettore andrà bene. Con oggetti come questo, la ragione principale per archiviare i puntatori sarebbe che un vettore può / copierà gli oggetti quando deve espandere la memoria per fare spazio a più oggetti. Se i tuoi oggetti sono così grandi e costosi da copiare che questo è inaccettabile, allora potresti voler memorizzare qualcosa come un puntatore nel vettore per ottenere copie e assegnazioni a basso costo. È probabile che non sia un puntatore non elaborato, ma probabilmente sarà una sorta di object puntatore intelligente che fornisce semantica più di valore, quindi la maggior parte degli altri codici può considerare l’object come un valore semplice e i dettagli del suo costoso operazioni e tali possono rimanere nascosti.

Non esiste un equivalente in C ++ di realloc ().

Miglior utilizzo:

 char* new_tmp = new (char*)[mtmp]; for (int n=0;n 

L'errore che si ottiene è perché il C ++ è meno indulgente con il cast di tipo implicito.