执行矩阵乘法时C中的分段错误
我使用gsl随机生成器生成两个大矩阵,并使用gsl cblas将它们相乘,但在cblas操作开始时,我总是遇到分割错误。当我不能解决这个问题时,我就写下面的代码,用最基本的思想做矩阵乘法,我仍然有分段错误,但当矩阵真的很小的时候,这两个都可以正常工作,我真的很困惑执行矩阵乘法时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
#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大小。谢谢,我在索引中犯了一个错误。当使用数组时,我总是犯同样的错误。谢谢你的帮助,我在索引中犯了一个错误。谢谢你的帮助,我在索引中犯了一个错误。