为什么我在调用 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);
我有一个 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);