链接和释放的C矩阵函数设计

链接和释放的C矩阵函数设计,c,matrix,memory-leaks,chaining,C,Matrix,Memory Leaks,Chaining,所以目前我正在使用一个为项目编写的小矩阵库,但我讨厌的是如何使用临时变量来存储指向矩阵的指针以避免内存泄漏 例如: matrix_t* matrix_add(matrix_t* m1, matrix_t* m2) { assert(m1 != NULL && m2 != NULL); assert(m1->rows > 0 && m2->rows > 0 && m1->cols > 0 &

所以目前我正在使用一个为项目编写的小矩阵库,但我讨厌的是如何使用临时变量来存储指向矩阵的指针以避免内存泄漏

例如:

matrix_t* matrix_add(matrix_t* m1, matrix_t* m2)
{
    assert(m1 != NULL && m2 != NULL);
    assert(m1->rows > 0 && m2->rows > 0 && m1->cols > 0 && m2->cols > 0);
    assert(m1->rows == m2->rows && m1->cols == m2->cols);

    matrix_t* sum = matrix_constructor(m1->rows, m1->cols);

    int i, j;
    for(i=0; i<m1->rows; i++)
    {
        for(j=0; j<m1->cols; j++)
        {
            matrix_set(sum, i, j, matrix_get(m1, i, j) + matrix_get(m2, i, j));
        }
    }
    return sum;
}
由于每个操作都需要一个临时变量,因此当有一个长的操作链时,这也会变得更加糟糕。我的问题是,有没有人有任何设计策略,能够通过连锁操作和避免内存泄漏,让我的生活更轻松,代码更干净


我想我可以发送一个带有可变长度操作的可变长度参数,但如果引入了许多不同的操作,例如矩阵转置和需要不同大小矩阵的操作,则可能会变得混乱。

一个解决方案是实现内存池管理器。分配内存后,主管将指针存储在列表中。当需要清理时,主管会释放其列表中的所有内存

顶层代码应该是这样的

mempool_t *pool = pool_create();
matrix_t *temp, *sum;
temp = matrix_add(pool, A, B);
temp = matrix_add(pool, temp, C);
temp = matrix_add(pool, temp, D);
sum  = matrix_add(pool, temp, E);
pool_destroy(pool, sum);
// ...
// use sum for something
// ... 
free(sum);
pool\u create
函数创建一个数据结构来跟踪所有内存分配。这可以是一个链表,也可以是一个可调整大小的数组

matrix\u add
函数将
pool
传递给构造函数

matrix_t *sum = matrix_constructor(pool, m1->rows, m1->cols);
matrix\u构造函数将分配的内存添加到池中

matrix_t *ptr = malloc(...);
pool_add(pool, ptr);

pool\u destroy
函数对列表中的每个指针调用
free
,作为第二个参数传递的指针除外。因此,在本例中,
sum
未被释放,随后必须由顶层代码释放。

为添加的结果定义第三个参数作为
matrix\u add
?这样,您就可以在两个
矩阵\u t
变量之间进行乒乓<代码>矩阵r1,r2;矩阵_添加(A、B和r1);矩阵_添加(&r1、C和r2);矩阵_添加(&r2、D和r1);矩阵_添加(&r1、E和r2)等。但该解决方案无法解决问题。我仍然需要在函数外释放矩阵,并且在某些情况下,我需要2个以上的临时变量。矩阵加法并不是唯一需要链接的情况。我个人认为调用函数来获取或设置矩阵元素有点过分。如果您愿意支付那么高的成本,那么我建议您使用像Python这样的非编译语言。使用C语言的唯一原因是为了速度,而你放弃了这一优势。问题是我正在为一个类编写它,稍后我将对它进行并行化,所以作业的重点是学习。此外,代码将在OpenMP、OpenMPI、,和Cuda都是C的衍生产品。你是对的,使用getter和setter是过度的,但我可以在将来将它们变成宏,我只是现在不想处理它们。传入一个矩阵数组,让函数一次完成整个链怎么样?我喜欢这个想法,作为清理代码的潜在方法... 它还可以让我像matrix_add(池,matrix_add(池,A,B),C)一样将它们链接在一起@BrianCrafton哦,是的,没错,我没想过,但那应该行得通。
matrix_t *ptr = malloc(...);
pool_add(pool, ptr);