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

使用fork()的C语言代码在ejudge平台出现Runtime Error的原因是什么?

代码触发Runtime Error的原因分析

1. 子进程逻辑错误导致进程数指数级暴涨

你的代码中,子进程成功通过scanf读取到单词后执行的是continue,会回到循环开头再次调用fork(),相当于每个成功读取单词的子进程都会继续创建新的子进程,进程数会指数级增长,很快超出ejudge平台的进程数限制,被系统强制杀死触发Runtime Error。本地测试时如果输入单词较少,可能刚好没触发进程数限制所以没有复现问题。
根据任务要求,每个进程最多读取1个单词,所以子进程读取到单词后应该直接以指定退出码退出,不应该继续循环创建进程。

2. 变量未初始化导致逻辑完全失控

你的循环从i=0开始执行,第一次fork操作发生在i=0阶段,但你只在i==1时才给first_child变量赋值,所以first_child初始是栈上的随机垃圾值,后续wait(&status) == first_child的判断逻辑完全不可控,会导致父进程随机提前退出、执行逻辑错乱。

3. 标准输入缓冲导致读取结果错乱

C标准库的stdin默认存在用户态缓冲区,fork()时会将父进程的缓冲区完整复制给所有子进程,导致多个子进程读到重复的缓冲内容,完全无法正确按顺序读取单词。

4. 计数逻辑完全不符合要求

你当前通过进程退出码传递计数的逻辑完全混乱,父进程没有正确累计所有成功读取单词的子进程数量,也无法正确判断所有子进程执行结束的时机。


修复后的参考代码
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>

int main() {
    // 关闭stdin用户态缓冲,避免多进程读重复内容
    setvbuf(stdin, NULL, _IONBF, 0);
    int word_count = 0;
    pid_t child_pids[255];
    int fork_cnt = 0;

    // 最多创建255个子进程对应最多255个单词
    for (int i = 0; i < 255; i++) {
        pid_t pid = fork();
        if (pid < 0) {
            exit(1);
        } else if (pid == 0) {
            // 子进程仅读取一次单词
            char buf[4097];
            if (scanf("%s", buf) != EOF) {
                // 读到单词则退出码为1
                exit(1);
            } else {
                // 读到EOF则退出码为0
                exit(0);
            }
        } else {
            child_pids[fork_cnt++] = pid;
        }
    }

    // 父进程等待所有子进程执行完毕,累计单词数
    for (int i = 0; i < fork_cnt; i++) {
        int status;
        waitpid(child_pids[i], &status, 0);
        if (WIFEXITED(status)) {
            word_count += WEXITSTATUS(status);
        }
    }

    printf("%d\n", word_count);
    fflush(stdout);
    return 0;
}

内容的提问来源于stack exchange,提问作者E1ZY

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 11:15:03