【发布时间】:2020-05-28 11:38:08
【问题描述】:
我对 C 编程有点陌生,我似乎不明白应该在哪里释放我初始化的 int* 数组。在我得到我需要的东西后,我尝试输入free(array),但 Valgrind 仍然报告我建议的位置存在内存泄漏和无效释放。我应该将free(array) 调用放在这段代码中的什么位置?
注意:删除实际代码实现是为了使代码更简单,同时保留错误。
// C-language code (C99)
#include <stdio.h>
#include <stdlib.h>
int fib(int index, int *array, int initBlocks);
int processFib(int index);
int doubleStorage(int **array, int initialBlocks);
int main() {
int ans = processFib(10);
printf("ans = %d", ans);
return 0;
}
// initialises an array and calls the fib(...) function
int processFib(int index) {
int defaultInitBlocks = 10;
int *array = calloc(defaultInitBlocks, sizeof(int));
array[1] = 1;
array[2] = 1;
int ans = fib(index, array, defaultInitBlocks);
free(array); /* Valgrind says InvalidFree here ----------------------*/
return ans;
}
// doubles storage of array using realloc
int doubleStorage(int **array, int initialBlocks) {
int factor = 2;
int *temp = realloc(*array, factor * initialBlocks * sizeof(int));
/* Valgrind says the realloc here is a DefinitelyLost memory leak --------*/
if (!temp) {
free(*array);
return -1;
} else {
*array = temp;
for (int i = initialBlocks; i < factor * initialBlocks; i++) {
(*array)[i] = 0;
}
return factor * initialBlocks;
}
}
// doubles storage if 'index' is greater than array storage. Else, returns 1
int fib(int index, int *array, int initBlocks) {
if (index >= initBlocks) {
int newBlocks = doubleStorage(&array, initBlocks);
return fib(index, array, newBlocks);
}
return 1;
}
编辑:解决方案移至答案
【问题讨论】:
-
使用 valgrind 的道具。两者都正确地陈述了他们的原因。尽管
fib算法的正确性,processFib中的array应该通过地址传递给fib,就像你传递给doubleStorage一样。这样做会将重新分配状态一直带回到processFib, where thefree` 可以按原样正确调用。 -
你可以通过摆脱动态分配和递归来极大地改进这个程序。
-
与您的问题无关:您应该通过检查
array的空指针来检查calloc(defaultInitBlocks, sizeof(int));的内存分配是否成功。如果它是一个空指针,你应该实现一个错误例程。 -
放置双指针后问题解决。是的,我应该检查
array是否有空指针。郑重声明,C 远非我最喜欢的语言。 -
@frostrivera19:请将您的解决方案写成下面的答案并接受它。 StackOverflow 不是您使用“已回答”或“已解决”编辑“帖子”的典型“表单”。
标签: c memory-leaks valgrind