Pergunta

Em uma pergunta anterior, perguntei sobre indicadores de tipo de tipo de tipo, mas fui direcionado para a melhor solução de usar o sistema de alocação C ++ em vez de mallocs. (Estou convertendo algum código C para C ++)

No entanto, ainda tenho um problema com uma função semelhante:

Eu mudei:

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

e

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

No entanto, o que eu faço com o realloc na seguinte função:

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;

Eu estou recebendo o seguinte erro:

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

Editar 2:

Ok, o consenso que estou recebendo é que devo abandonar minha solução atual (que estou aberto a fazer).

Só para garantir que eu esteja entendendo corretamente, vocês querem dizer que, em vez de uma variedade de ponteiros para objetos, eu deveria ter apenas um vetor contendo os próprios objetos?

Foi útil?

Solução

C permite void* ser implicitamente convertido em qualquer ponteiro. C ++ não, então se você está usando realloc, você deve lançar o resultado para o tipo apropriado.

Mas o mais importante, usando realloc em um ponteiro devolvido por new[] é comportamento indefinido. E não há C ++ direto-estilo equivalente a realloc.

Suas escolhas são, do menos ao mais idiomático:

  • Fique com malloc/realloc/free e lançar os ponteiros.
  • Usar new[] + delete[] ao invés de realloc
  • Usar std::vector<std::string> Em vez de gerenciar sua própria memória.

Outras dicas

Parece ser uma matriz não digna que cresce conforme necessário.

Pare de usar a alocação explícita de memória, você quase certamente não precisa dela. Usar std::vector ou outro dos contêineres dinâmicos da biblioteca padrão C ++ que crescem automaticamente conforme necessário para você.

Também parece que você está usando cordas de estilo C terminadas nulas. Por que não ser usado std::string em vez de?

No C ++, você não deve usar matrizes (mesmo alocados dinamicamente).

Isso foi substituído por std :: vetor

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

Em C ++

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

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

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

(Em resumo - não há realmente um equivalente a C ++ a realloc, mas talvez você seja melhor de usar um vector?)

O RealLoc não se importa realmente com os construtores de chamadas; portanto, usar o RealLoc após o novo parece uma má idéia. Você deve estar indo para o vetor como uma abordagem melhor. Você pode redimensionar vetores.

Infelizmente não há realloc em C ++ (devido ao fato de que a memória pode conter objetos não trivialmente construídos ou apenas não copiáveis). Alocar novo buffer e copiar ou aprender a usar std::vector ou std::stack Isso faria isso por você automaticamente.

Eu consideraria mudar da matriz dinâmica artesanal para um vetor uma boa primeira escolha.

Quanto a se o vetor deve conter objetos diretamente ou conter ponteiros para os objetos reais, não há uma única resposta definitiva - depende de vários fatores.

O principal fator único é se isso é o que eu chamaria de objetos de "entidade" - para os quais a cópia não faz sentido. Um caso clássico em questão seria algo como um iostream ou uma conexão de rede. Geralmente, não há maneira lógica de copiar ou atribuir um objeto como este. Se esse é o tipo de objeto com o qual você está lidando, você está praticamente preso armazenando indicadores.

Se, no entanto, você estiver lidando com o que geralmente é (vagamente) definido como "objetos de valores", copiar e atribuir será bom e armazenar os objetos diretamente no vetor ficará bem. Com objetos como esse, o principal motivo para armazenar ponteiros seria que um vetor pode copiar objetos quando precisar expandir a memória para abrir espaço para obter mais objetos. Se seus objetos forem tão grandes e caros para copiar que isso é inaceitável, convém armazenar algo parecido com um ponteiro no vetor para obter cópias e tarefas baratas. As chances são de que vai não Seja um ponteiro bruto-provavelmente será algum tipo de objeto de ponteiro inteligente que fornece uma semântica mais semelhante ao valor, para que a maioria dos outros códigos possa tratar o objeto como sendo um valor simples, e os detalhes de suas operações caras e tal pode permanecer escondido.

Não existe equivalente a C ++ do realloc ().

Melhor 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;

O erro que você está recebendo é porque o C ++ é menos branda com fundição de tipo implícito.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top