Errors when using realloc()
I am using realloc()
to dynamically size some arrays. Because I was writing a lot of code like this:
void *tmp;
if( (tmp = realloc(myobject, sizeof(object) * newsize) != NULL)
myobject = tmp
I thought I'd make my code shorter by doing something like this (silly idea):
void GetSpace(void *ptr, size_t size_of_object, int newsize){
void *tmp = NULL;
if ((tmp = realloc(ptr, size_of_object * newsize) == NULL)
//print error msg and exit
else
ptr = tmp;
}
int main(){
//This is an example
double *mydata1 = (double *)malloc (sizeof double * 5);
//later request more space for mydata1
GetSpace( mydata1, sizeof(double), 50);
}
This is silly since it doesn't save that many lines or make the code more readable but I'd like to know why it doesn't work the way I expect. When I use the GetSpace()
for a single object only it works fine. If I run the code without initializ开发者_JS百科ing any of the objects I call the function with, it runs fine but when I call GetSpace()
for an object, then put data in it and then call GetSpace()
for another object, I get a stack trace with a message like this
*** glibc detected *** ./a.out: realloc(): invalid old size: 0x00007fff05d96790 ***
0x00007fff05d96790
is the address of the second array/object before resizing. Why does this happen?
In your GetSpace
function, you are allocating a new block of memory with the bigger size, and assigning the address to the local variable ptr
. But when the function exits, this new address is lost. Your main program still has the old value of ptr
, which is now pointing to invalid (freed) memory.
You need to return the new address to the caller. Try this instead. Note that the parameter ptr
is now passed by reference, so the caller's variable is updated.
void GetSpace(void **ptr, size_t size_of_object, int newsize){
void *tmp = NULL;
if ((tmp = realloc(*ptr, size_of_object * newsize) == NULL)
//print error msg and exit
else
*ptr = tmp;
}
EDIT: as pointed out in the comments, this still isn't ideal, as you have to do messy casting to pass the address of your pointer as a void**
. An improvement would be to return the new pointer separately, as follows:
void *GetSpace(void *ptr, size_t size_of_object, int newsize){
void *tmp = NULL;
if ((tmp = realloc(ptr, size_of_object * newsize) == NULL)
//print error msg and exit
else
return tmp;
}
int main(){
...
//later request more space for mydata1
mydata1 = GetSpace( mydata1, sizeof(double), 50);
}
精彩评论