c -使用realloc()时的错误



我使用realloc()来动态调整一些数组的大小。因为我写了很多这样的代码:

void *tmp;
if( (tmp = realloc(myobject, sizeof(object) * newsize) != NULL)
         myobject = tmp

我想我可以这样做来缩短我的代码(愚蠢的想法):

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

这是愚蠢的,因为它没有节省那么多行或使代码更可读,但我想知道为什么它不像我期望的那样工作。当我使用GetSpace()为一个单一的对象只有它工作得很好。如果我在没有初始化调用函数的任何对象的情况下运行代码,它运行得很好,但是当我为一个对象调用GetSpace(),然后将数据放入其中,然后为另一个对象调用GetSpace()时,我得到一个堆栈跟踪,其中包含如下消息

*** glibc detected *** ./a.out: realloc(): invalid old size: 0x00007fff05d96790 ***

0x00007fff05d96790是调整大小之前的第二个数组/对象的地址。为什么会发生这种情况?

GetSpace函数中,您正在分配一个具有更大大小的新内存块,并将地址分配给局部变量ptr。但是当函数退出时,这个新地址将丢失。你的主程序仍然有旧的ptr值,它现在指向无效的(释放的)内存。

您需要将新地址返回给调用方。试试这个吧。注意,参数ptr现在是通过引用传递的,所以调用者的变量被更新了。

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:正如在评论中指出的那样,这仍然不是理想的,因为你必须做混乱的转换来传递你的指针地址作为void**。改进的方法是单独返回新指针,如下所示:

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

相关内容

  • 没有找到相关文章

最新更新