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

标签 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 && 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;
}

如您所见,如果我想像 2 个矩阵加法 (A + B + C) 那样将操作链接在一起,那么我将不得不执行如下操作:

matrix_t* temp = matrix_add(A, B);
matrix_t* sum = matrix_add(temp, C);
free_matrix(temp);

当有很长的操作链时,这也会变得更加丑陋,因为每个操作都需要一个临时变量。我的问题是,是否有人有任何设计策略可以通过链式操作和避免内存泄漏让我的生活更轻松、代码更简洁。

我想我可以发送一个带有可变长度操作的可变长度参数,但是当引入许多不同的操作(如矩阵转置和需要不同大小的矩阵的操作)时,这可能会变得困惑。

最佳答案

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

顶层代码看起来像这样

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_create 函数创建一个数据结构来跟踪所有内存分配。这可以是链表或可调整大小的数组。

matrix_add 函数将pool 传递给构造函数

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

matrix_constructor 将分配的内存添加到池中

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

pool_destroy 函数在列表中的每个指针上调用 free,作为第二个参数传递的指针除外。所以在这个例子中,sum 没有被释放,必须由顶层代码稍后释放。

关于用于链接和释放的 C 矩阵函数设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35593205/

相关文章:

c - 字符串数组未正确存储

c - 请帮助我理解这个 main() 代码

math - 创建人工相关矩阵

matlab - Matlab中如何将声音转换为矩阵?

python - 两个矩阵的元素之间的组合

c++ - 清除和删除多精度变量

c - 参数传递给函数

c - 如何从 Windows 上的套接字端口获取 PID?

ios - Flurry 分析 - NSAutoreleasePool allocWithZone :] - memory leak after upgrading to Objective-C ARC

c++ - 如何使用 Cuda 避免段错误时的内存泄漏