我正在尝试使用 OpenMP 实现具有动态内存分配的矩阵乘法。我设法让我的程序编译正常,但是当我尝试执行它时,我得到了./第 14 行:17653 分段错误(核心转储)./matrix.exe $matrix_size
int main(int argc, char *argv[]){
if(argc < 2){
printf("Usage: %s matrix/vector_sizen", argv[0]);
return 0;
}
int size = atoi(argv[1]);
double **matrix2 = (double **)malloc(sizeof(double*)*size);
double **matrix = (double **)malloc(sizeof(double*)*size);
double **result_sq = (double **)malloc(sizeof(double*)*size);
double **result_pl = (double **)malloc(sizeof(double*)*size);
int t;
for (t =0; t<size; t++) {
matrix[t]= (double *)malloc(sizeof(double)*size);
matrix2[t]= (double *)malloc(sizeof(double)*size);
result_pl[t]= (double *)malloc(sizeof(double)*size);
result_sq[t]=(double *)malloc(sizeof(double)*size);
}
matrix_vector_gen(size, matrix, matrix2);
我相信我使用带有双指针的malloc的方式导致了错误。
此外,该程序还包含以下函数,用于生成两个矩阵并按顺序执行一次乘法,使用 openMP 执行一次乘法。
void matrix_vector_gen(int size, double **matrix, double **matrix2){
int i,j;
for(i=0; i<size; i++)
for(j=0; j<size*size; j++)
matrix[i][j] = ((double)rand())/5307.0;
matrix2[i][j] = ((double)rand())/65535.0;
}
void matrix_mult_sq(int size, double **matrix2,
double **matrix_in, double **matrix_out){
int i, j, k;
for(i=0; i<size; i++){
for(j=0; j<size; j++)
matrix_out[i][j] = 0.0;
for(k=0; k<size; k++)
matrix_out[i][j] += matrix_in[i][k] * matrix2[k][j];
}
}
void matrix_mult_pl(int size, double **matrix2,
double **matrix_in, double **matrix_out){
int i, j, k;
# pragma omp parallel
shared(size, matrix2, matrix_in, matrix_out)
private(i,j,k)
# pragma omp for
for(i=0; i<size; i++){
for(j=0; j<size; j++)
matrix_out[i][j] = 0.0;
for(k=0; k<size; k++)
matrix_out[i][j] += matrix_in[i][k] * matrix2[k][j];
}
}
void matrix_vector_gen(int size, double **matrix, double **matrix2){
int i,j;
for(i=0; i<size; i++)
for(j=0; j<size*size; j++)
matrix[i][j] = ((double)rand())/5307.0;
matrix2[i][j] = ((double)rand())/65535.0;
}
当你只在循环中执行"for"语句之后的下一条语句时,只留下大括号,所以"matrix2"行在循环结束后执行,此时 i 和 j 是越界的,因此 (double*) matrix2[i] 是垃圾; 访问矩阵 2[i] 可能会导致也可能不会导致段错误,具体取决于堆布局, 但是访问Matrix2[i][j]很可能会,因为不知道它要去哪里。
这不是唯一的问题:matrix[i] 被分配为指向 sizeof(double) * size 数组的指针,而你在循环中访问矩阵 [i][size*size - 1]。
在C派生的语言中,省略"if","do","for","case"和"while"语句的大括号通常是一个坏主意;想象一下必须添加更多行,这可能会变得麻烦。当代码变得更加复杂时,也很难阅读和推理。