如何修复矩阵乘法多线程程序中的Segmentation Fault错误?
问题诊断与修复方案
你的多线程矩阵乘法程序出现段错误及逻辑问题,核心错误点如下:
1. 内层循环变量增量错误(直接触发段错误)
矩阵赋值的嵌套循环中,内层循环错误地使用i++作为增量,导致i快速超出矩阵范围,访问非法内存:
for (int i = 0; i < N; i++) { for (int j = 0; j < N; i++) // 错误:应改为j++ { args.A[i][j] = rand() % 100; args.B[i][j] = rand() % 100; args.T[j][i] = args.B[i][j]; } }
修复:将内层循环的i++改为j++,确保列索引正常遍历。
2. 变量初始化顺序错误
在未读取线程数n的情况下就计算args.rows,此时n是未定义的垃圾值,导致后续行范围计算完全失效:
args.rows = N/n; n = atoi(argv[1]);
修复:先读取线程数,再计算每行分配量,同时验证N是否能被n整除:
n = atoi(argv[1]); if (N % n != 0) { fprintf(stderr, "Error: N must be divisible by thread count\n"); exit(1); } args.rows = N/n;
3. 内存分配类型错误
分配矩阵每行时,错误使用sizeof(int*)代替sizeof(int),导致内存分配大小不符合实际需求(64位系统下会浪费一倍内存):
args.A[i] = (int*)malloc(N * sizeof(int*));
修复:改为sizeof(int),且C语言无需强制转换malloc返回值:
args.A[i] = malloc(N * sizeof(int)); args.B[i] = malloc(N * sizeof(int)); args.C[i] = malloc(N * sizeof(int)); args.T[i] = malloc(N * sizeof(int));
4. 线程共享参数的竞态条件
多个线程共享同一个myarg_t结构体,m->cur++不是原子操作,会导致多个线程拿到相同的起始行,出现重复计算或越界。
修复方案(互斥锁实现):
- 在结构体中添加互斥锁:
typedef struct __myarg_t { FILE *Aptr, *Bptr, *Cptr; int **A, **B, **C, **T; int rows; int cur; pthread_mutex_t mutex; // 新增互斥锁 } myarg_t; - 主线程初始化锁:
pthread_mutex_init(&args.mutex, NULL); - 线程函数中安全获取起始行:
void *mythread(void *arg) { myarg_t *m = (myarg_t *) arg; int start; pthread_mutex_lock(&m->mutex); start = m->cur++ * m->rows; pthread_mutex_unlock(&m->mutex); int end = start + m->rows; // 后续乘法逻辑不变 } - 程序结束前销毁锁:
pthread_mutex_destroy(&args.mutex);
5. 其他细节修复
- 检查文件打开是否成功:避免
fopen返回NULL后执行fprintf导致错误:args.Aptr = fopen("A_multi.txt", "w"); if (args.Aptr == NULL) { perror("Failed to open A_multi.txt"); exit(1); } // Bptr、Cptr同理添加检查 - 初始化随机数生成器:添加
srand(time(NULL))在矩阵赋值前,确保每次运行生成不同随机数。 - 修正拼写错误:
ptphread_join改为pthread_join。
内容的提问来源于stack exchange,提问作者rodew
相关产品推荐
相关产品推荐

