2016-06-20 49 views
0

我想在C中使用fork()做一個程序,但是當我在代碼中創建一個char數組時,程序會產生一個意外的結果(而不是創建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"); 
    } 
} 

如果試圖取消對數組的線,但從未使用過的結果改變了這種陣!

你能解釋我爲什麼嗎?

+1

結果有什麼變化? –

+2

'if(status [i] == 0)'在for之外,所以'i == NUM​​PROC':調用UB。 – LPs

+0

我剛用Eclipse試了一下,用線評論輸出是: '我是兒子號碼:0 我是兒子號碼:1 我是兒子號碼:2 我是兒子號碼:3 我兒子數:4 父terminated' 隨着線未註釋的輸出爲: '我兒子數量:0 我子數:1 我子數:2 I」 m兒子數量:5 我的兒子編號:3 我是兒子編號:4' – Niles

回答

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

上面的代碼中不正確父親的工作,因爲我將是等於NUMPROC,這應該是NUMPROC - 1

這是一個簡單的數組索引超出範圍的問題。 status[NUMPROC]的值未初始化,它的值可能會受到char數組的影響,因此您將得到不同的結果。

+0

好吧,我很愚蠢-.- – diegocom

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); 
} 
0

似乎有一個關於何時/何地發生從呼叫到fork()的每個可能的返回狀態出現的誤解以及如何處理子狀態。

所有孩子的行爲必須是for()循環中

所有父動作(除調用wait()需要是for()

孩子的行爲必須在呼叫終止exit()

推薦以下代碼:

  1. 完全編譯
  2. 執行所需操作
  3. 結合了初始評論OP上質疑

,現在,所提出的代碼

#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