char数组和fork的意外结果

时间:2016-06-20 08:30:21

标签: c arrays char fork

我试图在C中使用fork()编写一个程序,但是当我在代码中创建一个char数组时,程序会产生意想不到的结果。(而不是创建5个5个儿子,它会创建6个儿子?而且爸?)

代码是这个

#include <stdlib.h>
#include <stdio.h>
#define NUMPROC 5

int main (int argc, char *args[]){
    //UNCOMMENTTHIS LINE
    //char a[] = {'a','b','c','d','\0'};
    int i;
    pid_t status[NUMPROC];
    for(i = 0; i< NUMPROC; i++){
        status[i] = fork();
        //fork error
        if(status[i] == -1){
            perror("fork() error");
            exit(1);
        }
        //quit because I'm a son
        if(status[i] == 0)
            break;
    }

    //son
    if(status[i] == 0){
        printf("I'm son number: %i\n", i);
    }
    //father
    else{
        //wait sons
        for(i = 0; i < NUMPROC; i++){
            wait(&status[0]);
        }
        printf("Father terminated\n");
    }
 }

如果您尝试取消注释数组的行,结果会更改,但此数组永远不会被使用!

你能解释一下为什么吗?

3 个答案:

答案 0 :(得分:2)

添加指示的行,问题将很明显:

//son
if (i >= NUMPROC)     // add this line
    printf("ACK\n");  // and this line

if(status[i] == 0){
    printf("I'm son number: %i\n", i);
}

答案 1 :(得分:2)

//son
if(status[i] == 0){
    printf("I'm son number: %i\n", i);
}

以上代码在父亲中无法正常工作,因为我将等于NUMPROCNUMPROC - 1

这是一个简单的数组索引超出范围的问题。 status[NUMPROC]的值未初始化,char数组可能会影响其值,因此您会得到不同的结果。

答案 2 :(得分:0)

似乎存在对从fork()调用发生的每个可能返回状态的时间/位置以及如何处理子状态的误解。

所有子动作都需要在for()循环

之内

所有父操作(对wait()的调用除外)必须在for()循环内

子操作必须在调用exit()

时终止

建议以下代码:

  1. 干净地编译
  2. 执行所需的操作
  3. 包含对OPs问题的初步评论
  4. 现在,建议的代码

    #include <stdlib.h>    // exit(), EXIT_SUCCESS
    #include <stdio.h>     // printf()
    #include <unistd.h>    // fork(), pid_t
    #include <sys/types.h> // #defines for waitpid()
    #include <sys/wait.h>  // waitpid()
    
    #define NUMPROC (5)
    
    int main ( void )
    {
        int i;
        pid_t pid[NUMPROC] = {0};
    
        for(i = 0; i< NUMPROC; i++)
        {
            pid[i] = fork();
    
            switch( pid[i] )
            {
                case -1: // error
                    perror("fork() error");
                    // keep going, 
                    // so if any current child's exit,
                    // they do not become zombie processes
                    break;
    
                case 0: // child
                    printf("I'm son number: %i\n", i);
                    exit( EXIT_SUCCESS );
                    break;
    
                default: // parent
                    break;
            } // end switch
        } // end for
    
        //  only father gets here
        //wait sons
        for(i = 0; i < NUMPROC; i++)
        {
            if( -1 != pid[i] )
            { // then child process successfully created
                waitpid( pid[i], NULL, 0 );
            }
        }
        printf("Father terminated\n");
     }
    

    这是程序典型运行的输出:

    I'm son number: 0
    I'm son number: 1
    I'm son number: 4
    I'm son number: 2
    I'm son number: 3
    Father terminated