如何在C语言中乘两个动态矩阵?

如何在C语言中乘两个动态矩阵?,c,C,我试着通过一个函数把两个动态矩阵相乘。我在乘法过程中遇到了一个分段错误 矩阵通过一个函数传递。参数中的项是正确的,因为我必须将它们用于此项目中的其他操作。我有一种感觉,我把指针弄糟了,但我对C语言还很陌生,我不知道我把哪里弄糟了 double** multiplyMatrices( double** a, const uint32_t a_rows, const uint32_t a_cols, double** b, const uint32_t b_c

我试着通过一个函数把两个动态矩阵相乘。我在乘法过程中遇到了一个分段错误

矩阵通过一个函数传递。参数中的项是正确的,因为我必须将它们用于此项目中的其他操作。我有一种感觉,我把指针弄糟了,但我对C语言还很陌生,我不知道我把哪里弄糟了

double** multiplyMatrices(
    double** a,
    const uint32_t a_rows,
    const uint32_t a_cols,
    double** b,
    const uint32_t b_cols){

    uint32_t i = 0;
    uint32_t j = 0;
    uint32_t k = 0;
    double** c;

//allocate memory to matrix c
    c = (double **)malloc(sizeof(double *) * a_rows);
    for (i = 0; i < a_rows; i++) {
        *(c +i) = (double *)malloc(sizeof(double) * b_cols);
     }

//clear matrix c
    for(i = 0; i < a_rows; i++){
        for(j = 0; j < a_cols; j++){
            *c[j] = 0;
       }
    }

    i = 0;

//multiplication
    while(j = 0, i < a_rows ){
        while(k = 0, j < b_cols){
            while(k < a_cols){
                //following line is where i'm getting the segmentation fault
                *(*(c+(i*b_cols))+j) += (*(*(a+(i*a_cols))+k)) * (*(*(b+(k*b_cols))+j));
                k++;
            }
            j++;
        }
        i++;
    }
    return c;
}
double**多重矩阵(
双**a,
共32行,
警察局,
双**b,
const uint32_t b_cols){
uint32_t i=0;
uint32_t j=0;
uint32_t k=0;
双**c;
//将内存分配给矩阵c
c=(双**)malloc(sizeof(双*)*a_行);
对于(i=0;i
明显的错误是,当c是一个大小为
a\u行的指针数组时,您取消了对
c+i*b\u列的引用。很可能
c+i*b_cols
不在您先前分配给
malloc()的区域内

我建议使用大小等于元素总数的
double
单个数组简化矩阵表示,即行*列

例如:

double *c;

c = malloc(sizeof(double) * a_rows * b_cols);
c[i * b_cols + j] = ...
for (i = 0; i < a_rows; i++)
    for (j = 0; j < b_cols; j++)
       for (k = 0; k < a_cols; k++)
这不仅具有更好的总体性能,而且简化了代码。然后必须“线性化”一维数组内的偏移量,才能从二维矩阵坐标转换。例如:

double *c;

c = malloc(sizeof(double) * a_rows * b_cols);
c[i * b_cols + j] = ...
for (i = 0; i < a_rows; i++)
    for (j = 0; j < b_cols; j++)
       for (k = 0; k < a_cols; k++)
当然,其他两个矩阵需要以类似的方式进行分配、填充和访问

为了代码清晰,我还将用
For
语句替换
while
语句,并使用它们循环使用的实际变量。例如:

double *c;

c = malloc(sizeof(double) * a_rows * b_cols);
c[i * b_cols + j] = ...
for (i = 0; i < a_rows; i++)
    for (j = 0; j < b_cols; j++)
       for (k = 0; k < a_cols; k++)
for(i=0;i

你可以(ab)以多种方式使用C语言,但诀窍是首先要让你更清楚。

明显的错误是你取消了对
C+i*b_cols
的引用,而C是一个大小为
a_行的指针数组。很可能
c+i*b_cols
不在您先前分配给
malloc()的区域内

我建议使用大小等于元素总数的
double
单个数组简化矩阵表示,即行*列

例如:

double *c;

c = malloc(sizeof(double) * a_rows * b_cols);
c[i * b_cols + j] = ...
for (i = 0; i < a_rows; i++)
    for (j = 0; j < b_cols; j++)
       for (k = 0; k < a_cols; k++)
这不仅具有更好的总体性能,而且简化了代码。然后必须“线性化”一维数组内的偏移量,才能从二维矩阵坐标转换。例如:

double *c;

c = malloc(sizeof(double) * a_rows * b_cols);
c[i * b_cols + j] = ...
for (i = 0; i < a_rows; i++)
    for (j = 0; j < b_cols; j++)
       for (k = 0; k < a_cols; k++)
当然,其他两个矩阵需要以类似的方式进行分配、填充和访问

为了代码清晰,我还将用
For
语句替换
while
语句,并使用它们循环使用的实际变量。例如:

double *c;

c = malloc(sizeof(double) * a_rows * b_cols);
c[i * b_cols + j] = ...
for (i = 0; i < a_rows; i++)
    for (j = 0; j < b_cols; j++)
       for (k = 0; k < a_cols; k++)
for(i=0;i

您可以(ab)以多种方式使用C语言,但诀窍是首先让您更清楚地了解它。

清除矩阵C的方式似乎也有错误(除了不需要它之外)。外部循环中的变量i根本不在循环内部使用,因此您所做的只是将内部循环再重复一次。也不需要手动执行此操作,您可以使用
calloc()
而不是malloc。其参数的工作原理略有不同,但结果完全相同。如果要将任何内存区域全部归零,也可以使用
bzero()
memset()
。即使不会引发错误,清除“c”矩阵的代码也是错误的<代码>*c[j]
将在每次外部for循环迭代中引用完全相同的值集。使用@ThomasLeyk等更好的方法。不过,如果您想使用简单的方法,可以像
c[i][j]=0
c[i*a_rows+j]=0
那样使用它。清除矩阵c的方式似乎也有错误(除了不需要这样做之外)。外部循环中的变量i根本不在循环内部使用,因此您所做的只是将内部循环再重复一次。也不需要手动执行此操作,您可以使用
calloc()
而不是malloc。其参数的工作原理略有不同,但结果完全相同。如果要将任何内存区域全部归零,也可以使用
bzero()
memset()
。即使不会引发错误,清除“c”矩阵的代码也是错误的<代码>*c[j]
将在每次外部for循环迭代中引用完全相同的值集。使用@ThomasLeyk等更好的方法。不过,如果您想使用简单的方法,可以像
c[i][j]=0
c[i*a_行+j]=0
那样使用它。