【问题标题】:Matrix memory allocation through a function通过函数分配矩阵内存
【发布时间】:2017-10-07 08:02:27
【问题描述】:

我正在使用这些行来创建可变大小的矩阵:

Temp_Mat_0 = (double  **)malloc((M)*sizeof(double  ));
for (i=0;i<M;i++)
    Temp_Mat_0[i] = (double  *)malloc((N)*sizeof(double  ));

它们运行良好,但我一直在我的代码中反复使用它们。我需要将它们转换为传递指针和大小的函数。由于指针混乱,我无法做到。

matrixAllocate(Matrix Pointer,rows,colms)

你能帮忙吗!

【问题讨论】:

标签: c pointers matrix malloc


【解决方案1】:

他们工作正常

它们看起来不太好。代码应改为:

Temp_Mat_0 = malloc((M)*sizeof(double*));  //double* instead of double
if (Temp_Mat_0 == NULL)
    return;
for (i = 0; i < M; i++){
    Temp_Mat_0[i] = malloc((N)*sizeof(double));
    if (Temp_Mat_0[i] == NULL){
        free(Temp_Mat_0);
        return;
    }
}

然后,你可以使用这样的函数:

double ** matrix_pointer = matrixAllocate(rows,colms);

函数matrixAllocate 返回它分配的指针。例如:

matrixAllocate(rows,colms){
    Temp_Mat_0 = malloc((rows)*sizeof(double*));  
    if (Temp_Mat_0 == NULL)
        return NULL;
    for (i = 0; i < rows; i++){
        Temp_Mat_0[i] = malloc((colms)*sizeof(double));
        if (Temp_Mat_0[i] == NULL){
           free(Temp_Mat_0);
           return NULL;
        }
    }
    return Temp_Mat_0;
}

然后这样称呼它:

double **matrix pointer;
matrix pointer = matrixAllocate(rows, colms);

之后不要忘记释放malloced 内存。

for (i = 0; i < M; i++){
    free(Temp_Mat_0[i]);
}
free(Temp_Mat_0);

注意you should not cast the result of malloc,你也应该check if malloc was successful

【讨论】:

  • @LPs 如果 malloc 失败,则无法恢复程序,因为它的堆内存不足...此时,程序做什么并不重要,它必须关闭.
  • @Lundin 这真的取决于整个代码。堆没有损坏,因此可以以某种方式解决这种情况。
  • @LPs 不,它不会...您的程序无法将更多 RAM 硬件连接到计算机。在堆分配失败后继续执行是非常值得怀疑的做法。
  • @Lundin 显然不是这种情况,但我可以很容易地想象一个尝试分配并且失败的应用程序在等待队列中休眠,直到其他任务/线程完成它们的工作并释放堆内存......只是说:你写的是正确的,但“依赖于应用程序”
  • 我需要在你的代码中将 Temp_Mat_0 定义为 double**,对吧?
【解决方案2】:

我认为您最好使用一个非常简单的方案,将您的矩阵分配为单个连续块。

double **matrix_alloc(int rows, int cols)
{
    /* Allocate array of row pointers */
    double ** m = malloc(rows * sizeof(double*));
    if (!m) return NULL;

    /* Allocate block for data */
    m[0] = malloc(rows * cols * sizeof(double));
    if (!m[0]) {
        free(m);
        return NULL;
    }

    /* Assign row pointers */
    for(int r = 1; r < rows; r++) {
        m[r] = m[r-1]+cols;
    }

    return m; 
}

这有额外的好处,当你释放矩阵时,你不需要记住它有多大:

matrix_free( double** m )
{
    if (m) free(m[0]);
    free(m);
}

作为对此的扩展,您可以声明一个结构,该结构还跟踪它所拥有的行数和列数。 例如

struct matrix {
    int rows, cols;
    double **m;
};

这使您的矩阵函数看起来更好一些(您可以传递 struct matrix* 而不是 double**)。它的额外好处是矩阵维度与相关数据一起移动。

除非您有 巨大的 矩阵,否则通常最好对矩阵数据使用一个连续的块。如果您的矩阵很小,那就太好了,因为您将受益于 CPU 缓存中更好的内存局部性——这意味着更快的代码的潜力。

【讨论】:

  • 我有这个错误无法从 'void ' 转换为 'double **' 对于这一行 double ** m = malloc(rows * sizeof(double));是和windows还是VS有关
  • 您可能在不知不觉中使用了 C++ 编译器。只需像您在问题中所做的那样转换返回值即可。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-19
  • 1970-01-01
  • 2015-05-29
  • 2016-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多