【发布时间】:2018-09-16 04:24:38
【问题描述】:
我试图编写一个程序来使用 C 中的 OpenMP 执行矩阵乘法。每当我尝试将字符串文字作为参数传递给函数时,都会遇到分段错误错误。
#include<stdio.h>
#include<time.h>
#include<omp.h>
struct matrix{
int r;
int c;
int mat[1000][1000];
};
void read_matrix(char* fname, struct matrix* m){
FILE *fp;
fp = fopen(fname,"r");
fscanf(fp, "%d %d",&m->r,&m->c);
for(int i=0;i<m->r;i++){
for(int j=0;j<m->c;j++){
fscanf(fp, "%d", &m->mat[i][j]);
}
}
fclose(fp);
}
void write_matrix(char* fname, struct matrix m){
FILE *fp;
fp = fopen(fname,"w");
fprintf(fp,"%d %d\n",m.r,m.c);
for(int i=0;i<m.r;i++){
for(int j=0;j<m.c;j++){
fprintf(fp,"%d\n",m.mat[i][j]);
}
}
fclose(fp);
}
void main(){
struct matrix m1;
struct matrix m2;
struct matrix res;
read_matrix("m1",&m1);
read_matrix("m2",&m2);
int r1 = m1.r;
int c1 = m1.c;
int c2 = m2.c;
res.r = r1;
res.c = c2;
for(int i=0;i<r1;i++){
for(int j=0;j<c2;j++){
res.mat[i][j] = 0;
}
}
#pragma omp parallel
{
#pragma omp for
for(int i = 0; i < r1; i++){
for(int j = 0; j < c2; j++){
for(int k = 0; k < c1; k++){
#pragma omp atomic update
res.mat[i][j] += m1.mat[i][k]*m2.mat[k][j];
}
}
}
}
write_matrix("res",res);
}
代码在运行时显示Segmentation fault (core dumped)。
在 GDB 上运行时,它显示
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400ad9 in main () at mm.c:40
40 read_matrix("m1",&m1);
在第一次 read_matrix() 调用之前,我添加了一条 printf 语句 printf("check\n");
printf 调用现在开始引发分段错误。
我假设传递字符串文字是错误的原因。代码可能有什么问题?
【问题讨论】:
-
你检查
fopen()的返回值了吗? -
结构矩阵在 64 位上有 7 兆字节。
ulimit -s和ulimit -a在您的系统上的输出是什么?你的系统是 64 位的吗? -
您没有检查
m->r和m->c是否低于1000,任何高于1000 的值都可能导致越界访问和段错误。 -
对,
m->r和m->c的值是否低于 1000?你能显示示例输入吗?什么是预期的输出?(struct matrix)->mat是一个小数组,比如mat[10][10],这是否会发生? -
看起来 Afshin 解决了这个问题。
main()保留的堆栈空间多于可用空间,一旦您尝试调用任何函数并开始将参数数据推送到堆栈边界之外,程序就会崩溃。您需要动态分配这些结构,或将它们设为全局,或将它们设为static,以将它们移出堆栈。在本地分配的这个大小的变量是不行的。
标签: c