开发者

Errors when using realloc()

开发者 https://www.devze.com 2023-03-24 15:14 出处:网络
I am using realloc() to dynamically size some arrays. Because I was writing a lot of code like this: void *tmp;

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);
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号