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
lenvariable: You declaredint 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 thefilterarray size or as the length parameter forread/write. This is a major cause of your segmentation fault. - Wrong
printfformat specifiers:- In the child process,
printf("%s", filter[0]);uses%s(for strings) but passesfilter[0](a singlechar). This makesprintftreat 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%cfor single characters instead.
- In the child process,
- 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 writinglenbytes 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
fopenorpipesucceeded, 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
- Added error checks: Now the program will tell you if it can't open the file or create the pipe, instead of crashing silently.
- Removed uninitialized
len: We now read/write 1 byte at a time (since you're processing individual characters), which eliminates the random value issue. - Fixed
printfcalls: Used%cfor single characters instead of%s, which fixes the segmentation fault. - 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
readknow when to stop. - Added
wait(NULL): Ensures the parent waits for the child to finish before exiting, preventing zombie processes. - Used
ctype.hfunctions:islower,isupper,toupper, andtolowerare safer and more readable than manually adjusting ASCII values.
内容的提问来源于stack exchange,提问作者Alt
相关产品推荐
相关产品推荐

