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

标签 c gcc child-process execvp

我有一个 C 程序来创建一个子进程来运行命令“wc exec.c”。

下面是程序。

/* 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;
}

当子进程运行“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";

虽然我无法理解这个警告的含义,但gcc使用的“MAY”这个词给我的印象是“ok gcc gcc认为它可以在未初始化的情况下使用,但我已经初始化了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[ ] 不起作用的原因是什么?

谢谢。

最佳答案

因为你必须为其分配空间。

char *myargs[3];

您会自动为 3 个 char 指针分配空间,因此不会有问题,但是当您这样做时

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

关于c - 为什么在调用 execvp() 时不能使用 char **myargs 而不是 char *myargs[3]?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28552896/

相关文章:

c - 仅使用指针来打印数组的内容

c - 试图理解MD5算法

gcc - 在MinGw下构建完整的gcc

winapi - 我是否必须关闭子进程以后拥有的继承句柄?

unix - 子进程在 fork() 之后始终为零且始终唯一?

c++ - 运行时符号查找错误

c++ - 如何使用 C 中的内部 C++ 类类型?

c - 警告 : initialization makes integer from pointer without a cast

gcc - arm-linux-gcc 和 arm-none-linux-gnueabi 有什么区别

node.js - 在 IntelliJ IDEA 上调试 node.js child_process fork 示例