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?
The realloc() function changes the size of a previously reserved storage block. The ptr argument points to the beginning of the block. The size argument gives the new size of the block, in bytes. The contents of the block are unchanged up to the shorter of the new and old sizes.
No, the data will be copied for you into the new block that the returned p points at, before the old block is freed. This all happens before realloc returns, so the new p points to your data still.
Size of dynamically allocated memory can be changed by using realloc(). As per the C99 standard: void * realloc ( void *ptr, size_t size); realloc deallocates the old object pointed to by ptr and returns a pointer to a new object that has the size specified by size.
Since realloc may move the allocated memory to a new location, you need to account for this. Show activity on this post. Don't count on it staying at the same address. The system is allowed to move the whole affair to a different address for whatever reason.
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:
malloc
/realloc
/free
and cast the pointers.new[]
+ delete[]
instead of realloc
std::vector<std::string>
instead of managing your own memory.This appears to be an unremarkable array that grows as needed.
Stop using explicit memory allocation, you almost certainly have no need of it. Use std::vector
or another of the C++ standard library's dynamic containers that automatically grow as needed for you.
It also looks like you're using null-terminated C-style strings. Why not used std::string
instead?
In C++ you should not be using arrays (even dynamically allocated).
This has been replaced with 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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With