【问题标题】:Where should I put free() in C?我应该把 free() 放在 C 哪里?
【发布时间】: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 the free` 可以按原样正确调用。
  • 你可以通过摆脱动态分配和递归来极大地改进这个程序。
  • 与您的问题无关:您应该通过检查array 的空指针来检查calloc(defaultInitBlocks, sizeof(int)); 的内存分配是否成功。如果它是一个空指针,你应该实现一个错误例程。
  • 放置双指针后问题解决。是的,我应该检查array 是否有空指针。郑重声明,C 远非我最喜欢的语言。
  • @frostrivera19:请将您的解决方案写成下面的答案并接受它。 StackOverflow 不是您使用“已回答”或“已解决”编辑“帖子”的典型“表单”。

标签: c memory-leaks valgrind


【解决方案1】:

解决方案

现在在清除 Valgrind 警告的 fib() 函数中使用了双指针(代码如下)。前往@WhozCraig 发表评论。

int fib(int index, int **array, int initBlocks) {
    if (index >= initBlocks) {
        int newBlocks = doubleStorage(array, initBlocks);
        return fib(index, array, newBlocks);
    }
    if (array[index] > 0) {
        return (*array)[index];
    } else {
        (*array)[index] = fib(index - 1, array, initBlocks)
                + fib(index - 2, array, initBlocks);
        return (*array)[index];
    }
}

【讨论】:

    猜你喜欢
    • 2020-09-30
    • 2016-08-25
    • 2013-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-24
    • 2017-11-30
    • 2016-12-21
    相关资源
    最近更新 更多