C 会自动释放应用于函数的函数吗?

Posted

技术标签:

【中文标题】C 会自动释放应用于函数的函数吗?【英文标题】:Does C automatically free functions applied to functions? 【发布时间】:2022-01-08 00:21:08 【问题描述】:

我正在使用 C 中的矩阵并希望改进我的代码并确保没有内存泄漏。

我的矩阵实现如下:

typedef struct 
    int nb_cols;
    int nb_rows;
    float *data;
 matrix;

我有很多函数需要两个矩阵作为输入,然后返回一个输出。它们看起来像这样:

matrix *function(matrix* m1, matrix *m2)

    matrix* temp = matrix_init(m1->rows, m1->cols);

    // Doing some stuff 
    // like temp[i * (m1->cols) + j] = m1[ i * (m1->cols + j] + m2[i * (m2->cols + j];
    // (this is just an example)
    
    return temp;

当我这样调用这些函数时:

mat = function1(function2(m1, m2), m3);

编译器是否自动允许临时矩阵然后释放?还是我不应该这样做,并且拥有所有临时矩阵来一一免费地进行操作?

这样写更好吗?:

mat_temp = function2(m1, m2);
mat = function1(mat_temp, m3);
free(mat_temp);

非常感谢您的回答!

【问题讨论】:

您的建议更好,因为 malloc() 不知道它们的使用将是多么“临时” "free functions applied to functions" 应该是从嵌套函数中释放输出。释放函数意味着释放与函数关联的代码段,这可能不是您的意思。 【参考方案1】:

第二个更好。

在下面,function2() 返回的指针丢失了,因此分配给它的内存缺少对应的free()。 Memory leak

// lost memory
mat = function1(function2(m1, m2), m3);

改为:

matrix *m1 = function0();
matrix *m2 = function0();
matrix *mat_temp = function2(m1, m2);
matrix *mat = function1(mat_temp, m3);
free(mat_temp);
...
free(mat);
free(m2);
free(m1);

旁白:

改进我的代码

如果指向的数据没有变化,请添加const 以允许更广泛的功能使用和一些优化。

// matrix *function(matrix* m1, matrix *m2)
matrix *function(const matrix* m1, const matrix *m2)

如果调用代码应该从不提供重叠数据(没有意外的数据更改),请添加restrict 让编译器应用更多优化。

// matrix *function(matrix* m1, matrix *m2)
matrix *function(matrix* restrict m1, matrix * restrict m2)

... 或constrestrict

好的代码也会测试失败的分配。

if (m == NULL) TBD_code();

【讨论】:

感谢您的精彩回答。 另一个问题:m1 = multiply(m1, m2); 是否也会导致那些内存泄漏?就像回归自身并不能释放“以前存在”的东西,对吧? @Ouilliam 是的。最好使用 matrix *t = multiply(m1, m2); free(m1); m1 = t; 或编写另一个函数:void multiply_equal(matrix** m1, const matrix* m2); 并调用 multiply_equal(&m1, m2); 并让它以最佳方式重新分配 m1 数据。【参考方案2】:

编译器是否自动允许临时矩阵然后释放?

不,编译器不会自动释放它们。

你可以在 stack 上分配一些矩阵数据(使用 VLA - C99 中的可变长度数组功能),但如果你想将它传递给其他子程序,你必须使用堆(malloc、calloc、realloc 和 free,以及其他一些特定于平台的)

或者我不应该这样做,使用临时矩阵一个接一个地处理操作,然后释放临时矩阵

如果您不熟悉内存管理,并且愿意为了正确性而牺牲效率,那么 allocate-copy-free 并不是一个糟糕的策略。

但请相信我的话,因为我已经有一段时间没有使用内存管理进行编程了。

我最近的个人项目一直在做的是,我静态分配所有变量,首先估计最大必要内存,然后分配,并且在程序的整个生命周期中从不释放任何工作上下文。

【讨论】:

以上是关于C 会自动释放应用于函数的函数吗?的主要内容,如果未能解决你的问题,请参考以下文章

析构函数为啥能释放对象内存?

堆和栈的理解

C++面经漏洞汇总

为啥我的 IUnknown 释放函数会阻塞我的子线程?

堆和栈的区别

关于C语言free函数的问题