为什么我在调用 execvp() 时不能使用 char **myargs 而不是 char *myargs[3]?

Why cant I use char **myargs instead of char *myargs[3] while calling execvp()?

我有一个 C 程序可以为 运行 命令 "wc exec.c".

创建一个 child 进程

下面是程序。

/* Filename: exec.c*/

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

int main(int argc, char **argv)
{
    printf("Hello world (pid = %d).\n",(int) getpid());
    int ret = fork();
    if (ret < 0)
    {
            fprintf(stderr,"fork failed.\n");
            exit(1);
    }

    else if (ret == 0)
    {
            printf("I am the child process (pid = %d).\n",(int) getpid());

            // Launch command wc exec.c

            char *myargs[3];
            // char **myargs ;
            myargs[0] = "wc";
            myargs[1] = "exec.c";
            myargs[2] = NULL ;
            execvp(myargs[0], myargs);
            printf("Unreachable code\n");
    }

    else
    {
            int w = wait(NULL);
            printf("I am the parent of %d (pid = %d), w = %d\n", ret, (int) getpid(), w);
    }
    return 0;
}

这个程序给出了预期的输出,如 child 运行s "wc exec.c".

-bash-4.1$ ./a.out
Hello world (pid = 21362).
I am the child process (pid = 21363).
 45 115 789 exec.c
I am the parent of 21363 (pid = 21362), w = 21363
-bash-4.1$

只是为了玩玩,我想到了用 char **myargs 声明 char *myargs[3] 。 现在当我尝试编译 gcc 时给出警告。

-bash-4.1$ gcc -Wall exec.c
exec.c: In function âmainâ:
exec.c:32: warning: âmyargsâ may be used uninitialized in this function
-bash-4.1$

第32行就是这一行

  myargs[0] = "wc";

虽然我无法理解这个警告的意思,但是 "MAY" gcc used 给我的印象是“ok gcc gcc thinks it MAY be used uninitialized, but i have initialized myargs[0] = "wc",所以虽然可能有问题,但是没有问题。"

但是当我 运行 可执行文件时,我看到 execvp() 失败(因为 "wc exec.c")没有被执行。

-bash-4.1$ ./a.out
Hello world (pid = 21482).
I am the child process (pid = 21483).
I am the parent of 21483 (pid = 21482), w = 21483
-bash-4.1$

我阅读了 execvp 的手册页,它说,指针数组(作为 execvp() 的第二个参数传递)应该由 NULL 指针终止。我以为char **myargs 的第三个元素是NULL,所以满足那个条件。

在这种情况下,char **myargs 而不是 char *myargs[ ] 不起作用的原因是什么?

谢谢。

因为你要为它分配space。

char *myargs[3];

你自动为 3 个 char 指针分配 space,所以你没有问题,但是当你这样做时

char **myargs;

你有一个指向 char 指针的指针,所以如果你不指向任何地方而你试图访问它,你将导致未定义的行为。

要使用指向 char 指针的指针,您可以像这样通过 malloc() 使其指向有效内存

myargs = malloc(3 * sizeof(*myargs));
if (myargs == NULL)
    doNotContinue_AllocationFailure();
myargs[0] = "some constant string";

现在代码有效了。

但是您应该记住,当您不再需要 malloc()ed 指针时,必须 free()ed,因为您需要这样做

free(myargs);