Pregunta

En una pregunta anterior, me preguntó sobre typecasting punteros, pero fue dirigida a la mejor solución de utilizar el sistema de asignación de C ++ en lugar de mallocs. (Estoy convirtiendo algo de código C a C ++)?

Sin embargo, todavía tiene un problema con una función similar:

Me cambió:

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

y

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

Sin embargo, ¿qué hago con realloc en la siguiente función:

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;

Estoy consiguiendo el error siguiente:

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

EDIT 2:

De acuerdo, el consenso que estoy recibiendo es que debo abandonar mi solución actual (que estoy abierto a hacer).

Sólo para asegurarse de que estoy entendiendo correctamente, es lo que ustedes significan que, en lugar de una matriz de punteros a objetos, yo debería tener un vector que contiene los objetos mismos?

¿Fue útil?

Solución

C permite void* que se convierte implícitamente a cualquier puntero. C ++ no, por lo que si usted está utilizando realloc, que tiene que emitir el resultado al tipo apropiado.

Pero lo más importante, el uso de realloc en un puntero devuelto por new[] es un comportamiento indefinido. Y no hay C ++ directa -. Estilo equivalente a realloc

Las opciones son, de menos a más idiomática:

  • Se adhieren a malloc / realloc / free y emitir los punteros.
  • Uso new[] + delete[] en lugar de realloc
  • Uso std::vector<std::string> en lugar de la gestión de su propia memoria.

Otros consejos

Esto parece ser una serie anodina que crece a medida que sea necesario.

Detener el uso de la asignación de memoria explícita, es casi seguro que no tienen necesidad de ella. Uso std::vector u otro de los contenedores C ++ dinámicos de la biblioteca estándar que crecen automáticamente según sea necesario para usted.

También parece que estás usando cadenas estilo C terminadas en cero. ¿Por qué no se utiliza en lugar std::string?

En C ++ no se debe utilizar matrices (incluso asigna de forma dinámica).

Esto ha sido sustituido por std :: vector

En 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;
}

En C ++

std::vector<char*>   tmp(size);

// No need for free (destructor does that).
tmp.resize(newSize);

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

(En pocas palabras - no hay realmente un C ++ equivalente a realloc, pero quizá sería mejor de usar un vector)

realloc duerma verdaderamente se preocupan por llamar a los constructores, por lo que el uso de realloc después de nuevo parece una mala idea.You debe ir para el vector como un mejor enfoque. Puede cambiar el tamaño de los vectores.

Desafortunadamente no hay realloc en C ++ (debido al hecho de que la memoria puede contener objetos no trivialmente construidos o simplemente no copiable). O bien asignar nuevo buffer y copiar o aprender a usar std::vector o std::stack que hacer esto de forma automática.

Me gustaría considerar el cambio de la matriz dinámica hechos a mano a un vector de una buena primera opción.

Por lo que si el vector debe contener objetos directamente, o contienen punteros a los objetos reales, no hay una sola respuesta definitiva -. Depende de una serie de factores

El factor más importante es si estos son lo que yo llamaría objetos "entidad" - aquellos para los que la copia no tiene sentido. Un ejemplo clásico sería algo así como un iostream o una conexión de red. Generalmente no hay manera lógica para copiar o asignar un objeto como éste. Si ese es el tipo de objeto que está tratando, que está bastante atascado punteros de guardarlo.

Sin embargo, si usted está tratando con lo que generalmente (sin apretar) se define como "objetos de valor", la copia y la asignación va a estar bien, y el almacenamiento de los objetos directamente en el vector va a estar bien. Con los objetos de este tipo, la razón principal para almacenar punteros en lugar sería que un vector puede / copiar objetos de todo cuando se tiene que ampliar la memoria para hacer espacio para más objetos. Si los objetos son tan grandes y caras para copiar que esto es inaceptable, entonces es posible que desee guardar algo parecido puntero en el vector para obtener copia barata y asignación. Lo más probable es que la voluntad no ser un puntero en bruto sin embargo - probablemente será algún tipo de objeto puntero inteligente que proporcionan más valor similar a la semántica de manera más otro código puede tratar el objeto como un simple valor , y los detalles de sus operaciones costosas y tal puede permanecer oculto.

No hay C ++ equivalente de realloc ().

El mejor 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;

El error que está recibiendo es debido a que C ++ es menos indulgente con la fundición de tipo implícito.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top