Replacing realloc (C --> C++)

Biosci3c picture Biosci3c · Oct 6, 2010 · Viewed 10.3k times · Source

In an earlier question, I asked about typecasting pointers, but was directed to the better solution of using the C++ allocation system instead of mallocs. (I am converting some C code to C++)

However, I still have an issue with a similar function:

I changed:

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

and

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

However, what do I do with realloc in the following function:

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;

I am getting the following error:

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

EDIT 2:

Okay, the consensus I am getting is that I should ditch my current solution (which I am open to doing).

Just to make sure that I am understanding correctly, do you guys mean that, instead of an array of pointers to objects, I should just have a vector containing the objects themselves?

Answer

dan04 picture dan04 · Oct 6, 2010

C allows void* to be implicitly converted to any pointer. C++ doesn't, so if you're using realloc, you have to cast the result to the appropriate type.

But more importantly, using realloc on a pointer returned by new[] is undefined behavior. And there's no direct C++-style equivalent to realloc.

Your choices are, from least to most idiomatic:

  • Stick to malloc/realloc/free and cast the pointers.
  • Use new[] + delete[] instead of realloc
  • Use std::vector<std::string> instead of managing your own memory.