C 简单多个子执行器';试图从子对象的标准输出读取时发生错误

C 简单多个子执行器';试图从子对象的标准输出读取时发生错误,c,segmentation-fault,exec,fork,pipe,C,Segmentation Fault,Exec,Fork,Pipe,我设置了一个简单的fork示例来fork和exec2子对象,然后通过管道读取它们的输出,但是我有一个segfault(发生在close(piping[I][1]);并且无法找到原因。见下面的代码: #include <fcntl.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> int reader(int *piping

我设置了一个简单的fork示例来fork和exec2子对象,然后通过管道读取它们的输出,但是我有一个segfault(发生在close(piping[I][1]);并且无法找到原因。见下面的代码:

#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

int reader(int *piping[]) {
    char readstring[50];
    char readstring2[50];
    FILE *outPut;
    FILE *outPut2;
    outPut = fdopen(piping[0][0], "r");
    outPut2 = fdopen(piping[1][0], "r");
    fgets(readstring, sizeof(readstring), outPut);
    fgets(readstring2, sizeof(readstring2), outPut2);
    printf("%s\n", readstring);
    printf("%s\n", readstring2);
    return 0;
}

int main(void) {
    int i;
    int j;
    int pid;
    int **piping = malloc(sizeof(int*) *2);
    for(i = 0; i < 2; ++i) {
        piping[i] = malloc(sizeof(int) *2); 
    }   
    for(j = 0; j < 2; ++j) {
        pipe(piping[j]);
        if((pid = fork()) == -1)   
            fprintf(stderr, "error reading pipe\n");
            exit(1);
        } else if(pid == 0) {
            //child
            //close read pipes dup2 write pipes to stdout
            //then close old write pipes
            close(piping[j][0]);
            if(dup2(piping[j][1], 1) == -1) {
                fprintf(stderr, "error dup2");
                exit(2);
            }
            close(piping[j][0]);
            close(1);
            if(execlp("./playex", "playex", NULL)) {
                fprintf(stderr, "exec error\n");
            }
        } else {
            //parent
            close(piping[j][1]);
        }
    }
    reader(piping);
}
#包括
#包括
#包括
#包括
#包括
内部读取器(内部*管道[]){
字符读取字符串[50];
char readstring2[50];
文件*输出;
文件*outPut2;
输出=fdopen(管道[0][0],“r”);
输出2=fdopen(管道[1][0],“r”);
fgets(readstring,sizeof(readstring),输出);
fgets(readstring2,sizeof(readstring2),outPut2);
printf(“%s\n”,readstring);
printf(“%s\n”,readstring2);
返回0;
}
内部主(空){
int i;
int j;
int-pid;
内部**管道=malloc(尺寸(内部*)*2);
对于(i=0;i<2;++i){
管道[i]=malloc(内部尺寸)*2;
}   
对于(j=0;j<2;++j){
管道(管道[j]);
如果((pid=fork())=-1)
fprintf(stderr,“读取管道错误”);
出口(1);
}否则如果(pid==0){
//孩子
//关闭读管道dup2将管道写入标准输出
//然后关闭旧的写入管道
关闭(管道[j][0]);
如果(dup2(管道[j][1],1)=-1){
fprintf(标准“错误dup2”);
出口(2);
}
关闭(管道[j][0]);
关闭(1);
if(execlp(“./playex”,“playex”,NULL)){
fprintf(stderr,“exec error\n”);
}
}否则{
//母公司
关闭(管道[j][1]);
}
}
读卡器(管道);
}
上面是pipes和exec应该阅读的主要函数,下面是它运行的基本程序

#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

int main(void) {
    fprintf(stdout, "go\n");
}
#包括
#包括
#包括
#包括
#包括
内部主(空){
fprintf(stdout,“go\n”);
}
我已尝试修复segfault,但没有成功,请帮助查找和修复问题。

您的主要问题是(在编辑问题以隐藏其最初显示的内容之前)您在管道数组的边界之外编写:

for(i = 0; i < 2; ++i) {
    piping[i] = malloc(sizeof(int) *2); 
}   
for(j = 0; j < 2; ++j) {
    pipe(piping[i]);

现在,
i
将在第二个循环中未定义。

使用调试器。找出分段故障的位置。对不起,我忘了在关闭时包括它分段故障(管道[I][1]),这是我无法找出的。因为所有帐户我都需要关闭父级的写入端。使用malloc()时,一个管道将位于管道[0]处,另一个管道位于管道[1]处,这是我的文件集所在的位置。(我使用它是因为我需要通过参数将其调整为更大的比例,以便我可以将其细分为大小)。我不应该这样做吗?
execlp()
返回的唯一时间是当它失败时,因此您确实不需要测试它的返回值。但是,您应该在报告错误消息后退出。但是,这些都不会导致分段错误。为什么要关闭
close(1)
execlp()
之前,它小心地关闭刚刚设置为写入管道的标准输出。那会引起一些麻烦。您没有检查
fgets()
调用是否有效-或者
fdopen()
调用是否有效-因此您不知道使用您(可能或可能)读取的文件流或缓冲区是否安全。Yu在你的最小程序中有4个不必要的标题,打印
go
。是的,非常感谢我刚才注意到的,现在感觉自己像个白痴。欢迎来到俱乐部;有时我们都觉得自己像个白痴(但当你刚开始编程的时候,这种情况往往比你编程几年后发生的要多一些)。
for (int i = 0; i < 2; ++i) {
    piping[i] = malloc(sizeof(int) *2); 
}   
for (int j = 0; j < 2; ++j) {
    pipe(piping[i]);