【问题标题】:How do I free the memory that I allocated in a defined function later in my main function?如何释放我稍后在主函数中定义的函数中分配的内存?
【发布时间】:2021-12-05 19:09:20
【问题描述】:

我一直在为动态分配和释放它而苦苦挣扎,我知道我一直遇到此函数的内存泄漏问题,但我不知道如何正确释放它。

这是用malloc分配t然后返回主函数的函数:

double** transpose(int r, int c , double** arr) {
    double** t  = (double**) malloc(sizeof(double*) * c);
    for (int i = 0; i < c; i++) {
        t[i] = (double*) malloc(sizeof(double) * r);
    }
    for (int i = 0; i < r; i++) {
        for (int j = 0; j < c; j++) {
            t[j][i] = arr[i][j];
        }
    }
    return t;
}

这是最后需要释放的主要功能。让我感到困惑的是,我知道我需要循环到变量 c 并执行 free(t[i]),但是该变量超出了 main 的范围,因为它没有在那里声明。所以我不确定你应该如何免费访问它:

int main (int argc, char** argv){
    FILE* fp = fopen(argv[1], "r");
    if (fp == NULL) {
        printf("error\n");
        return 0;
    }
    fseek (fp, 0, SEEK_END);
    if (ftell(fp) == 0) {

        return 0;
    }
    
    FILE* fp2 = fopen(argv[2], "r");
    if (fp2 == NULL) {
        printf("error");
        return 0;
    }
    fseek (fp2, 0, SEEK_END);
    if (ftell(fp2) == 0) {

        return 0;
    }
    rewind(fp);
    rewind(fp2);

    
    int k = 0; 
    int n = 0;
    double z = 0.0;
    fscanf(fp, "%d", &k);
    fscanf(fp, "%d", &n);
    double** x = (double **) malloc(sizeof(double*) * n); 
    double** y = (double **) malloc(sizeof(double*) * n);
    for (int i = 0; i < n; i++) {
        x[i] = (double*) malloc((k + 1) * sizeof(double));
        y[i] = (double*) malloc(sizeof(double));
        for (int j = 0; j < (k + 2); j++) { 
            if (j == 0) { 
                x[i][j] = 1;
            } else if (j == k + 1) { 
                fscanf(fp, "%lf", &z);
                y[i][0] = z;
            } else { 
                fscanf(fp, "%lf,",&z);
                x[i][j] = z;
            }
        }
    }

    int m = 0;
    fscanf(fp2, "%d", &m);
    double** test = (double**) malloc(m * sizeof(double*));
    for (int i = 0; i < m; i++) {
        test[i] = (double*) malloc((k+1) * sizeof(double));
        for (int j = 0; j < (k+1); j++) {
            if (j != 0) {
                if (j == k+1) {
                    fscanf(fp2, "%lf", &z);
                    test[i][j] = z;
                }else {
                    fscanf(fp2, "%lf,", &z);
                    test[i][j] = z;
                }
            } else { 
                test[i][j] = 1;
            }
        }
    } 

    double** xt = transpose(n, (k+1), x);

    double** xxt = multiply((k+1), n, n, (k+1), xt, x);

    double** ixxt = inverse(k+1, xxt);

    double** ixxtxt = multiply((k+1), (k+1), (k+1), n,  ixxt, xt);

    double** w = multiply((k+1), n, n, 1, ixxtxt, y);

    

    double** ans = multiply(m, (k+1), (k+1), 1, test, w);
    print(m, 1, ans);
    fclose(fp);
    fclose(fp2);
    return 0;
}

【问题讨论】:

  • free()指针变量的指向的内存,而不是变量本身。地址数据在哪个变量中并不重要,只是它与之前malloc() 返回的 相同。所以free(xt) 但当然你首先需要一个循环到free() 它的每个元素,之前free(xt)
  • 从与t 相同范围内的任何位置调用free(ptr);,并指向与t 相同的地址。(其中ptr 是指向的变量与t 相同的内存位置在函数中。
  • 在同一级别分配和释放通常是更好的做法,最好在同一例程中。
  • @WeatherVane 所以在我的情况下,当我释放每个元素时,参数是什么? for(int i = 0; i
  • 与前面循环中用于分配每个元素的值相同(行数?)

标签: c memory-leaks malloc


【解决方案1】:

假设所有其他计算函数(multiply 等)不分配内存,您可以编写以下函数。使用单独的函数使代码更易于维护是一项设计决策。

void release(int c, double** p) {
    for (int i = 0; i < c; i++) {
        free(p[i]);
    }
    free(p);
}

注意1:如果其他计算函数分配了额外的内存,你也可以用它们返回的指针调用release()

注意 2:如果其他计算函数返回 相同的指针,因为它们作为参数接收,您实际上并不需要这个,因为值已“就地”更改。您可以将返回类型更改为void

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-06
    • 1970-01-01
    • 1970-01-01
    • 2012-07-31
    • 2016-07-16
    • 2014-09-26
    相关资源
    最近更新 更多