Reputation: 2720
I have a C program to create a child process to run command "wc exec.c".
Below is the program.
/* 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;
}
This program gives expected output, as child runs "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$
Just to play around I thought of declaring char *myargs[3] with a char **myargs . Now when I try to compile gcc gives a warning.
-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$
line 32 is this line
myargs[0] = "wc";
Although I could not understand the meaning of this warning, the word "MAY" gcc used gave me an impression that " ok gcc gcc thinks it MAY be used uninitialized, but i have initialized myargs[0] = "wc", so although there MAY be a problem, but there is no problem."
But when I run the executable, I see that execvp() fails (as "wc exec.c") is not executed.
-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$
I read the man pages for execvp, and it says, the array of pointer ( passed as second argument for execvp()) should be terminated by a NULL pointer. I thought that as the third element of char **myargs is NULL, this satisfies that condition.
Whats the reason for char **myargs to not work instead of char *myargs[ ] in this case ?
Thanks.
Upvotes: 0
Views: 173
Reputation: 53016
Because you have to allocate space for it.
With
char *myargs[3];
you automatically allocate space for 3 char
pointers, so you don't have a problem, but when you do
char **myargs;
your have a pointer to a char
pointer, so if you don't point with it anywhere and you try to access it, you will cause undefined behavior.
To use the pointer to char
pointer, you can make it point to valid memory via malloc()
like this
myargs = malloc(3 * sizeof(*myargs));
if (myargs == NULL)
doNotContinue_AllocationFailure();
myargs[0] = "some constant string";
and now the code is valid.
You should remember however, that the malloc()
ed pointer must be free()
ed when you no longer need it, for that you need to do this
free(myargs);
Upvotes: 1