执行矩阵乘法时C中的分段错误

执行矩阵乘法时C中的分段错误,c,segmentation-fault,matrix-multiplication,gsl,C,Segmentation Fault,Matrix Multiplication,Gsl,我使用gsl随机生成器生成两个大矩阵,并使用gsl cblas将它们相乘,但在cblas操作开始时,我总是遇到分割错误。当我不能解决这个问题时,我就写下面的代码,用最基本的思想做矩阵乘法,我仍然有分段错误,但当矩阵真的很小的时候,这两个都可以正常工作,我真的很困惑 #include <stdlib.h> #include <stdio.h> #include <math.h> #include <time.h> #define PI 3.14159

我使用gsl随机生成器生成两个大矩阵,并使用gsl cblas将它们相乘,但在cblas操作开始时,我总是遇到分割错误。当我不能解决这个问题时,我就写下面的代码,用最基本的思想做矩阵乘法,我仍然有分段错误,但当矩阵真的很小的时候,这两个都可以正常工作,我真的很困惑

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#define PI 3.1415926

void GenerateKey(int m, int n, int l, int q, float alpha)
{
    // initialization
    int i;
    int j;
    int k;

    float *A;
    float *S;
    float *E;
    float *B;

    float sigma = (alpha * q ) / sqrt(2 * PI);
    A=(float*)malloc(sizeof(float)*(m*n));
    S=(float*)malloc(sizeof(float)*(n*l));
    B=(float*)malloc(sizeof(float)*(m*l));
    E=(float*)malloc(sizeof(float)*(m*l));

    // init A
    for(i = 0; i < m*n; i++)
    {
        A[i]=0;
    }
    printf("\n");

    // init S
    for(i = 0; i < n*l; i++)
    {
        S[i]=0;
    }

    printf("\n");

    // init E
    for(i = 0; i < m*l; i++)
    {
        E[i]=0;
    }

    printf("\n");
    float po;
    for(i = 0; i < m; i++)
    {
        for(j=0; j<l; j++)
        {      
            po=0;
            for(k=0; k<n; k++)
            {
                po +=A[i*m+k]*S[k*n+j];
            }
            po += E[i*m +j];
            B[i*m+j]=((int)po) % q;
        }
    }

    printf("Game over");

    printf("\n");
    free(A);
    free(B);
    free(S);
    free(E);
}

int main()
{
    GenerateKey(2680,191,64,72973,0.000551);

    return 0;
}
#包括
#包括
#包括
#包括
#定义PI 3.1415926
void GenerateKey(int m,int n,int l,int q,float alpha)
{
//初始化
int i;
int j;
int k;
浮动*A;
浮动*S;
浮动*E;
浮动*B;
浮点西格玛=(α*q)/sqrt(2*PI);
A=(浮动*)malloc(浮动)*(m*n));
S=(浮动*)malloc(浮动)*(n*l)的大小;
B=(浮点数*)malloc(浮点数)*(m*l));
E=(浮点数*)malloc(浮点数)*(m*l));
//初始A
对于(i=0;i对于(j=0;j您没有检查
malloc()
返回值,因此我猜测一个或多个分配失败,您正在取消引用
NULL
。另一种可能性当然是索引错误,因此您可以越界访问。

您没有检查
malloc()
返回值,因此我猜测一个或多个分配失败,您正在取消引用
NULL
。另一种可能性当然是索引错误,因此您访问超出范围。

当您执行
i*m+j
时,这不应该是
i*l+j
?与
i*m+k
类似,应该是
i*l+k
k*n+j
应该是
k*l+j


原因是,以
E=(float*)malloc(sizeof(float)*(m*l))
为例,你有
m
行和
l
列(反之亦然),因此如果你在
m
维度上迭代,你需要乘以
m
迭代器(
i
)当你在做
i*m+j
的时候,你的矩阵在这个维度上的步幅是
l
,那不应该是
i*l+j
?同样的
i*m+k
应该是
i*l+k
,而
k*n+j
应该是
k*l+j


原因是,以
E=(float*)malloc(sizeof(float)*(m*l))
为例,你有
m
行和
l
列(反之亦然),因此如果你在
m
维度上迭代,你需要乘以
m
迭代器(
i
)通过该维度中矩阵的步长,即
l

,您错误地计算了所有矩阵的元素索引


当您有一个分配为一维数组的
MxN
矩阵时,元素
(i,j)
的索引是
i*N+j
。相反,您将其计算为
i*M+j

您错误地计算了所有矩阵的元素索引


当有一个
MxN
矩阵分配为一维数组时,元素
的索引(i,j)
i*N+j
。相反,您将其计算为
i*M+j

为什么要将这些矩阵视为一维数组?
gdb
表示错误在第78行,对于seg故障,只需使用
valgrind
gdb
。事实上,我想使用gsl cblas functt实现矩阵乘法离子,这个函数需要一维数组,因为这个函数也给了我分段错误,所以我写了这个程序,为什么你要把这些矩阵当作一维数组?
gdb
说错误在第78行,对于分段错误,只需使用
valgrind
gdb
使用gsl cblas函数进行矩阵乘法,这个函数需要一维数组,因为这个函数也给了我分段错误,所以我写这个程序只是为了补充:一个简单的检查方法是用数组索引中的最大值替换循环计数器。很容易立即看到I*m+k-->m*m+n很奇怪,因为A只是m*n大小。谢谢,我在索引时确实犯了一个错误。当使用数组时,我总是犯同样的错误。只需补充:一个简单的检查方法是用数组索引中可以接受的最大值替换循环计数器。很容易立即看出I*m+k-->m*m+n很奇怪,因为A是仅适用于m*n大小。谢谢,我在索引中犯了一个错误。当使用数组时,我总是犯同样的错误。谢谢你的帮助,我在索引中犯了一个错误。谢谢你的帮助,我在索引中犯了一个错误。