Question

Dans une question précédente, j'ai demandé typecasting pointeurs, mais il a été dirigé vers la meilleure solution d'utilisation du système d'allocation de C ++ au lieu de mallocs. (Je convertissant une partie du code C à C ++)

Cependant, j'ai encore un problème avec une fonction similaire:

Je changé:

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

et

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

Cependant, qu'est-ce que je fais avec realloc dans la fonction suivante:

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;

Je reçois l'erreur suivante:

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

EDIT 2:

D'accord, le consensus que je reçois est que je fossé ma solution actuelle (que je suis ouvert à faire).

Juste pour vous assurer que je comprends bien, avez-vous les gars signifie que, au lieu d'un tableau de pointeurs vers des objets, je devrais avoir un vecteur contenant les objets eux-mêmes?

Était-ce utile?

La solution

C permet void* à convertir implicitement à un pointeur. C ++ n'a pas, donc si vous utilisez realloc, vous devez jeter le résultat au type approprié.

Mais plus important encore, en utilisant realloc sur un pointeur retourné par new[] est un comportement non défini. Et il n'y a pas C ++ directe -. Le style équivalent à realloc

Vos choix sont, du moins au plus idiomatiques:

  • Stick to malloc / realloc / free et jeter les pointeurs.
  • Utilisez new[] + delete[] au lieu de realloc
  • Utiliser std::vector<std::string> au lieu de gérer votre propre mémoire.

Autres conseils

Cela semble être un tableau anodin qui pousse au besoin.

Arrêtez d'utiliser l'allocation de mémoire explicite, vous avez certainement pas besoin. Utilisez std::vector ou l'autre des C ++ des conteneurs dynamiques de bibliothèque standard qui poussent automatiquement au besoin pour vous.

Il semble aussi que vous utilisez à zéro terminal des chaînes de style C. Pourquoi ne pas utiliser à la place std::string?

En C ++, vous ne devriez pas utiliser des tableaux (même alloué dynamiquement).

Cela a été remplacé par std :: vector

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 bref - il n'y a pas vraiment un C ++ équivalent à realloc, mais vous seriez peut-être mieux d'utiliser un vector)

Realloc ne marche pas soin reallly à appeler les constructeurs, donc utiliser realloc après nouvelle semble être une mauvaise idea.You devrait aller pour le vecteur comme une meilleure approche. Vous pouvez redimensionner des vecteurs.

Malheureusement, il n'y a pas realloc en C ++ (en raison du fait que la mémoire peut contenir des objets non trivialement construits ou tout simplement non copiables). Soit allouer un nouveau tampon et copier ou apprendre à utiliser std::vector ou std::stack qui ferait automatiquement pour vous.

J'envisager de passer de la matrice dynamique de fabrication artisanale main à un vecteur un bon premier choix.

Quant à savoir si le vecteur doit contenir des objets directement ou contiennent des pointeurs vers les objets réels, il n'y a pas une seule réponse définitive -. Elle dépend d'un certain nombre de facteurs

Le plus grand facteur est de savoir si ce sont ce que j'appelle des objets « entité » - ceux pour lesquels la copie n'a pas de sens. Un exemple classique serait quelque chose comme un iostream ou une connexion réseau. Il y a généralement pas de façon logique de copier ou affecter un objet comme celui-ci. Si c'est le genre d'objet que vous avez affaire, vous êtes à peu près des pointeurs de mémorisation bloqué.

Par contre, si vous avez affaire à ce qui est généralement (vaguement) définis comme des « objets de valeur », la copie et l'affectation sera bien, et le stockage des objets directement dans le vecteur sera bien. Avec des objets comme celui-ci, la raison principale pour stocker des pointeurs serait plutôt qu'un vecteur peut / copie des objets autour quand il doit étendre la mémoire à la salle de faire pour plus d'objets. Si vos objets sont si grands et coûteux à copier que cela est inacceptable, alors vous voudrez peut-être stocker pointeur quelque chose dans le vecteur pour obtenir la copie et l'affectation pas cher. Il y a des chances que la volonté pas un pointeur brut bien - il sera probablement une sorte d'objet de pointeur intelligent qui offrent une plus grande valeur comme la sémantique si la plupart des autres code peut traiter l'objet comme étant une simple valeur , et les détails de ses opérations coûteuses et peuvent rester cachés tels.

Il n'y a pas C ++ équivalent de realloc ().

Meilleure utilisation:

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'erreur que vous obtenez est parce que C ++ est moins clémente avec la coulée de type implicite.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top