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

UNIX与C++管道编程遇段错误及进程异常,求排查解决

Fixing Your Segmentation Fault & Process Behavior Issues

Hey there! Let's break down the problems in your code step by step—your segmentation fault and unexpected parent process behavior come from several clear, fixable mistakes:

Key Issues in Your Original Code

  • Uninitialized len variable: You declared int len; but never assigned a value to it. This means it holds a random garbage value from memory, which causes chaos when you use it to define the filter array size or as the length parameter for read/write. This is a major cause of your segmentation fault.
  • Wrong printf format specifiers:
    • In the child process, printf("%s", filter[0]); uses %s (for strings) but passes filter[0] (a single char). This makes printf treat the character's ASCII value as a memory address, leading to an illegal memory access.
    • The parent process has the same mistake with printf("%s", ch);—use %c for single characters instead.
  • Incorrect pipe handling: After fork(), both processes hold both ends of the pipe. You need to close the unused ends (child closes write end, parent closes read end) to avoid unexpected blocking. Also, you were writing len bytes per character, but you only need to write 1 byte.
  • Redundant variables: char* toFilter; is never used—just delete it.
  • Missing error checks: You don't verify if fopen or pipe succeeded, which could lead to silent failures.

Corrected Code

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <ctype.h>
#include <sys/wait.h> // For wait()

int main() {
    FILE* fh = fopen("data.txt", "r");
    // Check if file opened successfully
    if (!fh) {
        perror("Failed to open data.txt");
        exit(EXIT_FAILURE);
    }

    int pipeID[2];
    // Check if pipe creation succeeded
    if (pipe(pipeID) == -1) {
        perror("Failed to create pipe");
        fclose(fh);
        exit(EXIT_FAILURE);
    }

    pid_t pid = fork();
    // Check if fork succeeded
    if (pid == -1) {
        perror("Failed to fork process");
        close(pipeID[0]);
        close(pipeID[1]);
        fclose(fh);
        exit(EXIT_FAILURE);
    }

    if (pid == 0) { // Child process: handle case swapping
        close(pipeID[1]); // Close unused write end
        char ch;
        // Read characters from pipe until parent closes write end
        while (read(pipeID[0], &ch, 1) > 0) {
            if (islower(ch)) {
                ch = toupper(ch);
            } else if (isupper(ch)) {
                ch = tolower(ch);
            }
            printf("%c", ch); // Print single character with %c
        }
        close(pipeID[0]); // Clean up: close read end
        exit(EXIT_SUCCESS);
    } else { // Parent process: read file and send to pipe
        close(pipeID[0]); // Close unused read end
        char ch;
        while ((ch = getc(fh)) != EOF) {
            printf("Parent read: %c\n", ch); // Optional debug print
            write(pipeID[1], &ch, 1); // Send 1 byte at a time
        }
        close(pipeID[1]); // Close write end so child knows no more data
        fclose(fh); // Clean up: close file
        wait(NULL); // Wait for child to finish to avoid zombie process
    }

    return 0;
}

What Changed & Why

  1. Added error checks: Now the program will tell you if it can't open the file or create the pipe, instead of crashing silently.
  2. Removed uninitialized len: We now read/write 1 byte at a time (since you're processing individual characters), which eliminates the random value issue.
  3. Fixed printf calls: Used %c for single characters instead of %s, which fixes the segmentation fault.
  4. Proper pipe cleanup: Closed unused pipe ends in each process, and the parent closes the write end after sending all data—this lets the child's read know when to stop.
  5. Added wait(NULL): Ensures the parent waits for the child to finish before exiting, preventing zombie processes.
  6. Used ctype.h functions: islower, isupper, toupper, and tolower are safer and more readable than manually adjusting ASCII values.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 19:07:41