声明char数组会导致execv()无效

时间:2013-11-26 15:10:41

标签: c unix pipe

我编写了以下代码,以便在c unix中使用管道:

#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]的声明代码停止工作。也就是说,没有提供输出。我试图重命名它,将decleration移动到if语句的开头。但没有任何效果。

那么,为什么程序在添加数组声明时会停止工作?

1 个答案:

答案 0 :(得分: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");