我有一小段代码(在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);
我想这最终会释放内存,但我真的不知道该怎么弄清楚。
答案 0 :(得分:1)
问自己的问题:
1)由于您没有错误检查,因此很难说您的alloc
是否正常工作
2)i
和memory
从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 == -5
假
1 == -5
假
2 == -5
假
3 == -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
且永不修改,i
从0
开始,并在循环的每次迭代时递增。所以你的循环比较:
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
。
另请注意,您永远不会检查calloc
或realloc
的结果。虽然使用现代操作系统使内存操作失败的可能性极小,但您不应该忽略错误的可能性。
答案 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()
的返回值。