C 创建新流程时出现分段错误(堆芯转储)

C 创建新流程时出现分段错误(堆芯转储),c,segmentation-fault,C,Segmentation Fault,首先,由于我发布的另一个问题是一个小阴影,我要求删除该线程,并有点想用这个线程替换它 我可以从解释我的程序应该做什么开始: 程序应该创建几个运行printenv、grep[inputarray]、sort、less的进程,然后这些进程应该使用管道来传输数据,如下所示: printenv->pipe1->grep->pipe2->sort->pipe3->less->stdout 现在我通过调用函数“createProcesswithPipe”递归地完成了这项工作。。 我相信这个计划背后的理论是正

首先,由于我发布的另一个问题是一个小阴影,我要求删除该线程,并有点想用这个线程替换它

我可以从解释我的程序应该做什么开始: 程序应该创建几个运行printenv、grep[inputarray]、sort、less的进程,然后这些进程应该使用管道来传输数据,如下所示: printenv->pipe1->grep->pipe2->sort->pipe3->less->stdout

现在我通过调用函数“createProcesswithPipe”递归地完成了这项工作。。 我相信这个计划背后的理论是正确的

现在如果你看一下代码,你会看到

printf("point: %d" , pointer); 
每次输入函数时打印指针的值。。现在的问题是,如果程序按原样运行,它永远不会打印出来。有什么想法吗

但如果我要进一步删除递归调用:

createProcesswithPipe(++pointer, executes, execute);
程序在得到相同的错误之前打印出“点:0”:分段错误(堆芯转储)

也不要介意瑞典语的评论!如果你有任何问题,请提问!我有点迷路了:)

/*digenv.c-dig(ta reda på)env(环境变量)*/
#包括
#包括
#包括
#包括
#包括
#包括
#定义管道读取侧(0)
#定义管道写入侧(1)
pid_t childpid;/*för child processens PID vid fork()*/
void createProcesswithPipe(int指针,int执行,char*执行[])
{
printf(“点:%d”,指针);
int pipe_filedesc[2];/*för Fildesktriptorer från管道(2)*/
int return_value;/*för returvärden från systemanrop*/
return_value=pipe(pipe_filedesc);/*skapa en pipe*/
if(-1==返回_值){perror(“无法创建管道”);exit(1);}/*om pipe()misslyckades*/
childpid=fork();/*skapa första child processen*/
如果(0==childpid)
{
返回值=dup2(管道文件描述[管道读取侧],标准文件号);
如果(-1==返回_值){perror(“Cannot dup”);退出(1);}
/*这是一个很好的参考,直到管道被安装在里面*/
返回值=关闭(管道文件描述[管道读取侧]);
如果(-1==返回_值){perror(“无法关闭读取端”);退出(1);}
/*这根管子只能读*/
返回值=关闭(管道文件描述[管道写入侧]);
如果(-1==返回_值){perror(“无法关闭写入端”);退出(1);}

如果(指针)尝试将
printf(“点:%d”,指针);
更改为
printf(“点:%d\n,指针);
。额外的
\n
(换行符)应该会导致缓冲区刷新。(我猜它在刷新缓冲区之前崩溃。)这非常有用:)现在它打印:Point:0 Point:1 Point:2 Point:3 Point:4实际上它不是一个指针,它是一个名为pointer的int,因为我来自java,我就是这么做的:PYou应该使用调试器,只依赖printfs进行调试要困难得多。就像@Étienne所说的,你真的应该使用调试器。我只是想快速解释一下为什么你需要eren没有得到任何输出。假设您使用的是
gcc
,如果您通过
gdb
运行程序,您可以使用
backtrace
命令来确定SEGFAULT来自哪一行,检查堆栈,等等。您可以查看。您也可以用瑞典语找到一个。谢谢,我会查看它:)
/* digenv.c - dig (ta reda på) env (enviroment variablar) */
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define PIPE_READ_SIDE ( 0 )
#define PIPE_WRITE_SIDE ( 1 )

pid_t childpid; /* för child-processens PID vid fork() */


void createProcesswithPipe(int pointer, int executes, char* execute[])
{
    printf("point: %d" , pointer);

    int pipe_filedesc[ 2 ]; /* för fildeskriptorer från pipe(2) */
    int return_value; /* för returvärden från systemanrop */

    return_value = pipe( pipe_filedesc ); /* skapa en pipe */
    if( -1 == return_value ) {perror( "Cannot create pipe" ); exit( 1 );} /* om pipe()     misslyckades */

    childpid = fork(); /* skapa första child-processen */

    if( 0 == childpid )
    {
        return_value = dup2( pipe_filedesc[ PIPE_READ_SIDE], STDIN_FILENO );
        if( -1 == return_value){perror( "Cannot dup" ); exit( 1 );}

        /* TA BORT GAMLA REFERENSEN TILL PIPE BEHÖVER INTE HA 2st!!!!!!! */
        return_value = close( pipe_filedesc[PIPE_READ_SIDE] );
        if( -1 == return_value ){perror( "Cannot close read end" ); exit( 1 );}

        /* THIS PIPE SHOULD ONLY READ */
        return_value = close( pipe_filedesc[PIPE_WRITE_SIDE] );
        if( -1 == return_value ){perror( "Cannot close write end" ); exit( 1 );}

        if(pointer <= 3){
            createProcesswithPipe(++pointer, executes, execute);
        }
        else if(3 == pointer && executes < 4){
            return_value = dup2( STDOUT_FILENO, pipe_filedesc[ PIPE_WRITE_SIDE] );
            if( -1 == return_value){perror( "Cannot dup" ); exit( 1 );}

            /* TA BORT GAMLA REFERENSEN TILL PIPE BEHÖVER INTE HA 2st!!!!!!! */
            return_value = close( pipe_filedesc[ PIPE_WRITE_SIDE ] );
            if( -1 == return_value ){perror( "Cannot close read end" ); exit( 1 );}

            (void) execlp( execute[executes], execute[executes], (char *) 0 );
        }
        else
        {
            return_value = dup2( STDOUT_FILENO, pipe_filedesc[ PIPE_WRITE_SIDE] );
            if( -1 == return_value){perror( "Cannot dup" ); exit( 1 );}

            /* TA BORT GAMLA REFERENSEN TILL PIPE BEHÖVER INTE HA 2st!!!!!!! */
            return_value = close( pipe_filedesc[ PIPE_WRITE_SIDE ] );
            if( -1 == return_value ){perror( "Cannot close read end" ); exit( 1 );}

            char* execute2[executes-4];
            int i;
            for(i = 1;i<executes-4;i++){
                execute2[i] = execute[i+3];
            }
            (void) execlp( execute[executes], execute[executes], (char *) execute2 );
        }
    }
    else
    {

        if( -1 == childpid ){   perror( "Cannot fork()" );  exit( 1 );}  /* fork() misslyckades */

        return_value = dup2( pipe_filedesc[ PIPE_WRITE_SIDE], STDOUT_FILENO );
        if( -1 == return_value){perror( "Cannot dup" ); exit( 1 );}

        /* Kommer vi hit i koden så är vi i parent-processen
         och fork() har fungerat bra. */

        /* THIS PIPE SHOULD ONLY WRITE */
        return_value = close( pipe_filedesc[ PIPE_READ_SIDE ] );
        if( -1 == return_value ){perror( "Cannot close read end" ); exit( 1 );}

        /* TA BORT GAMLA REFERENSEN TILL PIPE BEHÖVER INTE HA 2st!!!!!!! */
        return_value = close( pipe_filedesc[ PIPE_WRITE_SIDE ] );
        if( -1 == return_value ){perror( "Cannot close read end" ); exit( 1 );}

        (void) execlp( execute[executes], execute[executes], (char *) 0 );

        /* exec returnerar bara om något fel har uppstått
         och om exec returnerar så är returvärdet alltid -1 */
        perror( "Cannot exec &execute[executes]" );
        exit( 1 );

    }
}




int main( int argc, char * argv[] )
{
    char* execute[3+argc-1];

    execute[0] = "printenv";
    execute[3+argc-3] = "sort";
    execute[3+argc-2] = "less";

    int i;
    for(i = 3;i<(3+argc-1);i++)
    {
        if(!(strcmp(argv[i-3], "more"))){
            execute[3+argc-2] = "more";
        }
        else{
            execute[i] = argv[i-3];
        }
    }

    createProcesswithPipe(0, (3+argc-1), execute);

    exit( 0 ); /* Avsluta parent-processen på normalt sätt */
}