为什么这个realloc实例给了我SIGABRT?

时间:2016-07-13 07:05:22

标签: c

这是有问题的代码,它是一个重新分配int数组并在其末尾添加数字的函数

int *add_to_array(int *arr, unsigned int num, int newval)
{
    if(arr != NULL){

        int *newarr = realloc(arr, sizeof(int) * (num+1));
            if(!newarr){
                free(arr);

            }else{
                free(newarr);
            }
            arr[num] = newval;
            return arr;
   }
   else{

    return NULL;

   }

}

问题是,当我调用此函数一次时,它工作正常,但如果我第二次调用它,调试器会给我一行SIGABRT

int *newarr = realloc(arr, sizeof(int) * (num+1));

以下是我调用函数的方法

array = add_to_array(array, 5, 10);
array = add_to_array(array, 6, 100);

编辑:我设法用这个新代码解决了这个问题

int *add_to_array(int *arr, unsigned int num, int newval)
{
if(arr != NULL){

int *newarr =realloc(arr, sizeof(int) * (num+1));
if(!newarr){
    return NULL;
}else{
 newarr[num] = newval;
 return newarr;
}
}
else{

    return NULL;

}

}

还有一个问题,在realloc无法重新分配给定指针arr的情况下,arr在该实例中是否为null或者它是否仍然有效?

3 个答案:

答案 0 :(得分:2)

不仅没有

    else{
           free(newarr); 
        }

有意义,但也违背了

的目的
int *newarr = realloc(arr, sizeof(int) * (num+1));

如果realloc成功,请执行arr=newarr

<强>参考

[ realloc ]参考说:

  

成功时,将指针返回到新分配的开头   记忆。必须使用free()或者释放返回的指针   realloc的()。原始指针ptr无效并且可以访问任何内容   它是未定义的行为(即使重新分配就位)。

     

失败时,返回空指针。原始指针ptr仍然存在   有效且可能需要使用free()或realloc()解除分配。

答案 1 :(得分:1)

如果realloc失败,你可能想要保存旧数组并且什么也不做,所以:

        if(!newarr){
            free(arr);

应该是:

        if(!newarr){
            return NULL // Allocation fails, the old array saved. Check the return value outside the function 
        }

如果realloc成功,你肯定不想释放新数组,只需更新其中的最后一个值,所以:

        }else{
            free(newarr);
        }
        arr[num] = newval;
        return arr;

应该是:

        newarr[num] = newval;
        return newarr;

答案 2 :(得分:1)

当您尝试在重新分配后写入原始块时,您的代码会导致未定义的行为。如果重新分配失败 - 您在写入之前手动释放该块,在其他情况下,您不得触摸该块,因为realloc()已返回新块并且原始一个托架在内部被释放。 SIGABRT - 是一个特定于实现的通知,关于检测到的堆损坏或滥用malloc-family API。仔细阅读realloc()