Domanda

In una precedente interrogazione, ho chiesto di typecasting puntatori, ma era diretto alla soluzione migliore di utilizzare il sistema di assegnazione C ++ invece di mallocs. (I sono la conversione del codice C al 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, che 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; j<systems_stack[i].nplanets; j++) {
         if(systems_stack[i].planets[j]->real == ASSET_REAL) {
            ntmp++;
            if (ntmp > mtmp) { /* need more space */
               mtmp += CHUNK_SIZE;
               tmp = realloc(tmp, sizeof(char*) * mtmp); <--- Realloc
            }
            tmp[ntmp-1] = systems_stack[i].planets[j]->name;

Sto ottenendo il seguente errore:

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

EDIT 2:

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

Solo per fare in modo che io sto capendo bene, voi ragazzi significa che, invece di un array di puntatori a oggetti, vorrei solo avere un vettore che contiene il loro oggetti?

È stato utile?

Soluzione

C permette void* da convertito in modo implicito qualsiasi puntatore. C ++ non, quindi se si sta utilizzando realloc, è necessario lanciare il risultato al tipo appropriato.

Ma ancora più importante, utilizzando realloc su un puntatore restituito da new[] è un comportamento indefinito. E non c'è C ++ diretta -. Stile equivalente a realloc

Le scelte sono, dal meno al più idiomatica:

  • Stick per malloc / realloc / free e gettato i puntatori.
  • Usa new[] + delete[] invece di realloc
  • Usa std::vector<std::string> invece di gestire la propria memoria.

Altri suggerimenti

Questo sembra essere un array insignificante che cresce come necessario.

Smettere di usare l'allocazione della memoria esplicita, è quasi certamente non hanno bisogno di esso. Utilizzare std::vector o l'altro dei contenitori dinamici della libreria standard C ++ che crescono automaticamente come necessario per voi.

Sembra inoltre che si sta utilizzando le stringhe di C-stile null-terminated. Perché non utilizzato std::string invece?

In C ++ non si dovrebbe usare array (anche assegnato dinamicamente).

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<char*>   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 C ++ equivalente a realloc, ma forse si sarebbe meglio di utilizzare una vector)

Realloc pretende molto idoneo ad accogliere preoccupa di chiamare i costruttori, in modo da utilizzare realloc dopo il nuovo sembra una cattiva idea.You dovrebbe andare per il vettore come un approccio migliore. È possibile ridimensionare vettori.

Purtroppo non c'è realloc in C ++ (a causa del fatto che la memoria potrebbe contenere oggetti non banalmente costruiti o semplicemente non copiabili). O allocare nuovo buffer e copiare o imparare ad usare std::vector o std::stack che avrebbe fatto questo per voi automaticamente.

avrei considerazione il passaggio dalla matrice dinamica prodotta artigianalmente un vettore una buona scelta.

Per quanto riguarda se il vettore deve contenere oggetti direttamente, o contenere i puntatori agli oggetti reali, non c'è una sola risposta definitiva -. Dipende da una serie di fattori

Il singolo fattore più grande è se si tratta di quello che io chiamerei "entità" oggetti - quelli per i quali la copia non ha senso. Un caso classico nel punto sarebbe qualcosa come un iostream o di una connessione di rete. Non c'è generalmente alcun modo logico per copiare o assegnare un oggetto come questo. Se questo è il tipo di oggetto hai a che fare con, sei praticamente bloccato puntatori stoccaggio.

Se, invece, hai a che fare con quello che sono generalmente (vagamente) definito come "oggetti di valore", la copia e l'assegnazione andrà bene, e memorizzare gli oggetti direttamente nel vettore andrà bene. Con oggetti come questo, il motivo principale per memorizzare i puntatori invece sarebbe che un vettore può / copierà oggetti intorno quando deve espandere la memoria per fare spazio per più oggetti. Se gli oggetti sono così grandi e costosi da copiare che questo è inaccettabile, allora si potrebbe desidera memorizzare qualcosa di puntatore come nel vettore per ottenere la copia a buon mercato e l'assegnazione. Le probabilità sono che la volontà non essere un puntatore RAW anche se - probabilmente sarà una sorta di oggetto puntatore intelligente che forniscono più semantica di valore simile quindi la maggior parte altro codice in grado di trattare l'oggetto come un semplice valore , ei dettagli delle sue operazioni costose e tale può rimanere nascosto.

Non v'è alcun C ++ equivalente di realloc ().

Miglior uso:

char* new_tmp = new (char*)[mtmp];
for (int n=0;n<min(mtmp,oldSize);n++) new_tmp[n] = tmp[n];
delete [] tmp;  // free up tmp
tmp = new_tmp;

L'errore che si sta ottenendo è causa C ++ è meno indulgente con il casting di tipo implicito.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top