Calloc& realloc:`./a.out':free()出错:下一个大小无效(正常)

时间:2014-11-12 20:56:05

标签: c free realloc calloc

我有一小段代码(在C中)我在其中分配一个数组并扫描数字。如果数组太小,我正在为我的数组重新分配内存。有时它工作正常,但有时会返回“./a.out'中的错误:free():下一个大小无效(正常)。”

以下是代码:

int *array;
int memory=0, i=0, scanreturn=0;
array = (int *)calloc(30, sizeof(int));
/*Allocating 30 ints*/
while ( scanf("%d", &array[i]) != EOF){
  if(i == (memory - 5)){
    /*There's only 5 ints left. Allocating 10 more*/
    memory = memory + 10;
    array = (realloc(array, memory * sizeof *array));
  }
  i++;
}
...
free(array);

我想这最终会释放内存,但我真的不知道该怎么弄清楚。

5 个答案:

答案 0 :(得分:1)

问自己的问题:

1)由于您没有错误检查,因此很难说您的alloc是否正常工作
2)imemory从0开始,何时会被调用realloc
2a)如果realloc未被调用,当你到达原始alloc时会发生什么?

附:切勿投射alloc的结果 P.P.S.
i 0,1,2,3 ......的值 memory 0,0,0,0,0,.....的值 memory - 5 -5,-5,-5,-5,.....的值 if (i == (memory - 5))
0 == -51 == -52 == -53 == -5假 ......

正如您所看到的,这将花费很长时间才能为假

答案 1 :(得分:1)

根据i和内存的起始条件,你永远不要在循环中输入if语句
if(i == (memory - 5)),永远不会重新分配数组,并且当你将scanf()扫描到你正在写出的数组中时界限。这是未定义的行为,并且通常会覆盖一些内部数据,因为当您调用free()时会收到警告。

答案 2 :(得分:1)

int *array;
int memory=0, i=0, scanreturn=0;
array = (int *)calloc(30, sizeof(int));
/*Allocating 30 ints*/
while ( scanf("%d", &array[i]) != EOF){
  if(i == (memory - 5)){

我们在这里有什么?这个if 如何触发? memory设置为0且永不修改,i0开始,并在循环的每次迭代时递增。所以你的循环比较:

 i == (memory - 5)  result
 0 == (0 - 5)        false
 1 == (0 - 5)        false
 2 == (0 - 5)        false
           ...
30 == (0 - 5)        false
31 == (0 - 5)        false

因此,您永远不会进入尝试增加缓冲区的代码,最终导致缓冲区溢出。在那之后,你处于未定义的行为状态,任何事情都会发生。

明显的解决方案?设置memory = 30而不是memory = 0

另请注意,您永远不会检查callocrealloc的结果。虽然使用现代操作系统使内存操作失败的可能性极小,但您不应该忽略错误的可能性。

答案 3 :(得分:0)

查看您发布的代码,

int *array;
int memory=0, i=0, scanreturn=0;
array = (int *)calloc(30, sizeof(int));
/*Allocating 30 ints*/
while ( scanf("%d", &array[i]) != EOF){

  // ***********************************************
  // This conditional will never be true since
  // memory has been initialized to 0.
  // ***********************************************
  if(i == (memory - 5)){
    /*There's only 5 ints left. Allocating 10 more*/
    memory = memory + 10;
    array = (realloc(array, memory * sizeof *array));
  }

  // ***********************************************
  // What happens when 1 == 30?
  // You start writing over out of bounds memory, leading to undefined behavior.
  // ***********************************************
  i++;
}
...
free(array);

如果您正确初始化memory,则使用

的目的
  if(i == (memory - 5)){

会被送达。改变行

int memory=0, i=0, scanreturn=0;

int memory=30, i=0, scanreturn=0;

解决问题。

答案 4 :(得分:0)

清理代码版本:

int memory=0, i=0;
array = calloc(30, sizeof(int));

while (scanf("%d", &array[i]) != EOF) {
  if (i == (memory - 5)) {
    memory = memory + 10;
    array = realloc(array, memory * sizeof *array);
  }
  i++;
}

您需要初始化memory = 30。使用memory = 0,您的比较将变为if (i == -5)...,永远不会调用realloc()

如果分配失败,您还应该检查calloc()realloc()的返回值。