多文件统计数字1的线程程序出现Segmentation Fault错误求助
问题修复方案
核心错误分析
你的代码运行出现段错误以及功能异常,主要有以下几个问题:
- 线程数组越界:
pthread_t thread[ar]的索引范围是0到ar-1,但你循环时用i从1到ar访问thread[i],直接越界访问内存导致段错误。 - 空文件指针未终止函数:当
fopen返回NULL(文件不存在)时,你没有终止线程函数,后续继续调用fgetc(fp)会访问空指针,触发段错误。 - 字符判断错误:文本文件中的数字'1'对应的ASCII值是
49,你用(int)ch ==1判断的是ASCII控制字符SOH,完全不符合需求。 - 无线程同步:多个线程同时修改全局变量
global,会出现竞态条件,导致统计结果不准确。 - 线程函数无返回值:
pthread要求线程函数必须返回void*类型值,你的func函数没有返回语句,属于未定义行为。 - 不符合作业输出要求:文件不存在时不允许报错,但你代码里会打印"No text file...",而且最终输出格式和示例不一致。
修改后的完整代码
#include <stdio.h> #include <stdlib.h> #include <pthread.h> int global = 0; pthread_mutex_t mutex; // 用于线程同步的互斥锁 void* func(void *argp) { char *filename = (char*)argp; FILE *fp = fopen(filename, "r"); char ch; int local_count = 0; // 先统计到局部变量,减少锁竞争 if (fp == NULL) { pthread_exit(NULL); // 文件不存在直接退出线程 } // 统计文件中'1'的数量 while ((ch = fgetc(fp)) != EOF) { if (ch == '1') { local_count++; } } fclose(fp); // 关闭文件,避免资源泄漏 // 加锁更新全局变量 pthread_mutex_lock(&mutex); global += local_count; pthread_mutex_unlock(&mutex); return NULL; // 符合线程函数返回要求 } int main(int argc, char *argv[]) { int file_count = argc - 1; pthread_t *threads = NULL; // 初始化互斥锁 if (pthread_mutex_init(&mutex, NULL) != 0) { fprintf(stderr, "Mutex initialization failed\n"); return 1; } if (file_count > 0) { // 动态分配线程数组,避免栈溢出(文件数量多时更安全) threads = (pthread_t*)malloc(file_count * sizeof(pthread_t)); if (threads == NULL) { fprintf(stderr, "Memory allocation failed\n"); pthread_mutex_destroy(&mutex); return 1; } // 创建线程:索引从0到file_count-1,避免越界 for (int i = 0; i < file_count; i++) { if (pthread_create(&threads[i], NULL, func, (void*)argv[i+1]) != 0) { fprintf(stderr, "Failed to create thread for %s\n", argv[i+1]); // 已创建的线程需要join,避免资源泄漏 for (int j = 0; j < i; j++) { pthread_join(threads[j], NULL); } free(threads); pthread_mutex_destroy(&mutex); return 1; } } // 等待所有线程完成 for (int i = 0; i < file_count; i++) { pthread_join(threads[i], NULL); } free(threads); } // 按照示例格式输出结果 printf("Total Number of Ones in All Files: %d\n", global); // 销毁互斥锁 pthread_mutex_destroy(&mutex); return 0; }
关键修改说明
- 修复数组越界:线程数组索引改为从
0开始,循环范围匹配数组实际长度。 - 空指针处理:文件不存在时直接调用
pthread_exit(NULL)终止线程,避免后续非法访问。 - 修正字符判断:将
(int)ch ==1改为ch == '1',正确匹配文本中的数字字符。 - 添加线程同步:使用
pthread_mutex_t互斥锁保护全局变量global的修改,避免多线程竞态条件。 - 局部计数优化:先将每个文件的统计结果存在局部变量,再一次性更新全局变量,减少锁的持有时间,提升效率。
- 动态分配线程数组:避免栈上创建大数组导致栈溢出,更适合文件数量较多的场景。
- 符合输出要求:移除文件不存在时的错误打印,最终输出格式和作业示例完全一致。
- 资源清理:添加文件关闭、内存释放、互斥锁销毁等操作,避免资源泄漏。
编译与运行说明
编译时需要链接pthread库:
gcc main.c -o main -lpthread
运行方式完全符合作业示例,比如:
- 单个文件:
./main 1-10.txt - 多个文件:
./main 8-10.txt 5-10.txt - 通配符:
./main *-10M.txt - 无参数:
./main
内容的提问来源于stack exchange,提问作者novice
相关产品推荐
相关产品推荐

