C语言多线程数组排序程序出现Segmentation Fault问题求助
解决多线程数组排序的Segmentation Fault问题
首先,咱们来逐个排查你代码里导致段错误和逻辑错误的核心问题:
1. 数组长度计算函数boyutbul的致命错误
你用while(the[++number]!='\0')来计算数组长度,但你的数组是int类型数组,不是字符串。你生成的随机数范围是1+rand()%1500,数组里根本不会有'\0'(也就是整数0),这个循环会一直越界访问内存,直接触发Segmentation Fault。
修复方案:
不需要动态计算数组长度,因为你已经明确知道dizi1是300个元素、dizi2是500个元素、dizi3是800个元素。可以用结构体包装数组指针、长度和序号,作为参数传给线程函数。
2. 数组赋值时的索引越界错误
给dizi2赋值的错误
原代码里:
else { dizi2[i-(500)-1]= orginal_dizi[i]; }
当i从300开始时,i-500-1会得到负数(比如i=300时是-201),这会越界访问dizi2的内存,导致未定义行为。正确的索引应该是i-300,这样从0到499正好对应dizi2的500个元素。
合并到dizi3时的错误
原代码里:
else { dizi3[i]=dizi2[i-500]; }
同样,i从300开始时,i-500是负数,正确的应该是i-300,对应dizi2的0到499索引。
3. 随机数未初始化种子
你没有调用srand(time(NULL)),每次运行程序生成的随机数序列都是固定的,加上这个可以让每次生成的随机数不同。
4. 合并逻辑的错误(非段错误但影响结果)
你原来的合并只是简单把dizi1和dizi2拼到dizi3,这样dizi3并不是有序的!需要用归并排序的合并逻辑才能得到真正有序的合并数组。
修改后的完整代码
#include <stdio.h> #include <pthread.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> #include <time.h> #define SIZE 800 #define SIZE1 300 #define SIZE2 500 int original_dizi[SIZE], dizi1[SIZE1], dizi2[SIZE2], dizi3[SIZE]; // 定义结构体,用来给线程传递数组指针、长度和序号 typedef struct { int* arr; int len; int index; } ThreadData; void* runner(void *param) { ThreadData* data = (ThreadData*)param; int temp, i, k; int* bolum = data->arr; int sayi = data->len; int arr_index = data->index; printf("\n----------unsorted %d. array-----------\n\n", arr_index); for(i=0; i<sayi; i++) { printf("%d\n", bolum[i]); } // 冒泡排序逻辑保留 for(i=0; i<sayi; i++) { for(k=0; k<(sayi-i-1); k++) { if(bolum[k] > bolum[k+1]) { temp = bolum[k]; bolum[k] = bolum[k+1]; bolum[k+1] = temp; } } } printf("\n----------sorted %d. array-----------\n\n", arr_index); for(i=0; i<sayi; i++) { printf("%d\n", bolum[i]); } free(data); // 释放结构体内存 pthread_exit(NULL); } int main() { pthread_t tid1, tid2, tid3; int i=0; // 初始化随机数种子 srand(time(NULL)); // 生成不重复的随机数逻辑保留 while(i < SIZE) { int yenisayi = 1 + rand()%1500; int aynimi = 0, j=0; while(j < i) { if(original_dizi[j] == yenisayi) { aynimi = 1; break; } j++; } if(aynimi) continue; original_dizi[i] = yenisayi; i++; } // 修正dizi1和dizi2的赋值索引 for(i=0; i<SIZE; i++) { if(i < SIZE1) { dizi1[i] = original_dizi[i]; } else { dizi2[i - SIZE1] = original_dizi[i]; } } // 创建第一个线程处理dizi1 ThreadData* data1 = malloc(sizeof(ThreadData)); data1->arr = dizi1; data1->len = SIZE1; data1->index = 1; pthread_create(&tid1, NULL, runner, (void*)data1); pthread_join(tid1, NULL); // 创建第二个线程处理dizi2 ThreadData* data2 = malloc(sizeof(ThreadData)); data2->arr = dizi2; data2->len = SIZE2; data2->index = 2; pthread_create(&tid2, NULL, runner, (void*)data2); pthread_join(tid2, NULL); // 用归并逻辑合并两个已排序数组到dizi3 int p1 = 0, p2 = 0, p3 = 0; while(p1 < SIZE1 && p2 < SIZE2) { if(dizi1[p1] < dizi2[p2]) { dizi3[p3++] = dizi1[p1++]; } else { dizi3[p3++] = dizi2[p2++]; } } // 处理剩余元素 while(p1 < SIZE1) { dizi3[p3++] = dizi1[p1++]; } while(p2 < SIZE2) { dizi3[p3++] = dizi2[p2++]; } // 创建第三个线程处理dizi3 ThreadData* data3 = malloc(sizeof(ThreadData)); data3->arr = dizi3; data3->len = SIZE; data3->index = 3; pthread_create(&tid3, NULL, runner, (void*)data3); pthread_join(tid3, NULL); // 写入文件逻辑保留 FILE *fp; if((fp = fopen("son.txt","w")) == NULL) { printf("Dosya acilamadi."); return 1; } for(i=0; i<SIZE; i++) { fprintf(fp, "%d\n", dizi3[i]); } fclose(fp); return 0; }
编译与运行提示
注意编译命令的顺序:gcc -pthread -O soru1.c -o soru1,然后运行./soru1即可。
内容的提问来源于stack exchange,提问作者Türkü Doğan
相关产品推荐
相关产品推荐

