You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多文件统计数字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;
}

关键修改说明

  1. 修复数组越界:线程数组索引改为从0开始,循环范围匹配数组实际长度。
  2. 空指针处理:文件不存在时直接调用pthread_exit(NULL)终止线程,避免后续非法访问。
  3. 修正字符判断:将(int)ch ==1改为ch == '1',正确匹配文本中的数字字符。
  4. 添加线程同步:使用pthread_mutex_t互斥锁保护全局变量global的修改,避免多线程竞态条件。
  5. 局部计数优化:先将每个文件的统计结果存在局部变量,再一次性更新全局变量,减少锁的持有时间,提升效率。
  6. 动态分配线程数组:避免栈上创建大数组导致栈溢出,更适合文件数量较多的场景。
  7. 符合输出要求:移除文件不存在时的错误打印,最终输出格式和作业示例完全一致。
  8. 资源清理:添加文件关闭、内存释放、互斥锁销毁等操作,避免资源泄漏。

编译与运行说明

编译时需要链接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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 17:01:09