2013-11-26 23 views
0

我寫下面的代碼,以便在C UNIX使用管道:聲明char數組導致execv()到不行

#include <stdio.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <unistd.h> 
#include <string.h> 

int main() 
{ 
    int fds[2]; 
    pid_t pid; 
    /* Create a pipe. File descriptors for the two ends of the pipe are 
    placed in fds. */ 
    pipe (fds); 
    /* Fork a child process. */ 
    pid = fork(); 
    if (pid == (pid_t) 0) { 
     //char abc[10]; - **Uncommenting this cause the program not to work.** 
     /* This is the child process. Close our copy of the write end of 
     the file descriptor. */ 
     close (fds[1]); 
     // Read params 
     FILE * stream; 
     stream = fdopen (fds[0], "r"); 
     char* args[4]={"avg3.out","4","3","5"}; 

     /* Replace the child process with the 「avg3」 program. */ 
     execv("avg3.out", args); 
    } else { 
     /* This is the parent process. */ 
     FILE* stream; 
     /* Close our copy of the read end of the file descriptor. */ 
     close (fds[0]); 
     /* Convert the write file descriptor to a FILE object, and write 
     to it. */ 
     dup2(fds[0], STDOUT_FILENO); 
     stream = fdopen (fds[1], "w"); 
     fprintf (stream, "5 4 3"); 
     fflush (stream); 
     close (fds[1]); 
     /* Wait for the child process to finish. */ 
     waitpid (pid, NULL, 0); 
    } 
    return 0; 
} 

avg3.out是我以前編譯的文件。它只是計算髮送給它的3個參數的平均值。

輸出爲4,但是當我試圖從流中實際讀取時,我添加了一個char buffer[10]的聲明代碼停止工作。也就是說,沒有提供輸出。我試圖重新命名它,以將刪除移至if語句的開頭。但沒有任何工作。

那麼,爲什麼在添加數組聲明時程序停止工作?

回答

1

要調用exec*()的參數數組需要爲(char*)NULL終止。

此行

char* args[4]={"avg3.out","4","3","5"}; 

應該

char* args[] = {"avg3.out", "4", "3", "5", NULL}; 

由於它是不是在你的代碼,exec()可能會迷路尋找它。

運氣不好,堆棧可能已經乾淨(0填寫)爲您的代碼不聲明aexecv()發現NULL的指針指向"5"之後的版本。在堆棧上創建了a,然後更改了堆棧的內容,使execv()迷失搜索NULL


此外值得一提的是,OP的代碼在大部分相關的系統調用中沒有檢查錯誤。

這樣做以及詳細解釋錯誤的原因,可能通過使用致電perror()的呼叫可能導致通過提供相關信息來解決此問題。

特別是將其放置在調用execv()後,它很快將是顯而易見的什麼是錯的:

execv("avg3.out", args); 
perror("execv() failed");