Reputation: 252
This code makes a segmentation fault:
int main(int argc, char *argv[]){
int *n;
*n = atoi(argv[1]);
printf("n: %d \n", *n);
return 0;
}
while this works:
int main(int argc, char *argv[]){
int *n;
*n = atoi(argv[1]);
pid_t pid = fork();
if (pid == 0)
return 0;
else
printf("n: %d \n", *n);
return 0;
}
Why the second with the fork works? I know that after int *n
, I should allocate space for an int
with a malloc()
, but using the fork()
seems to do this automatically.
edit: Now I understand Undefined behavior :) But now I'm asking: what is the cause in this specific case?
Upvotes: 5
Views: 653
Reputation: 297
it happens that you do not see the segfault as when running fork and returns 0, your code never runs printf ("% d", *n)
The segmentation foult occurs when you try to access a memory location that is not allowed, so the solution is to assign ana memory through malloc or calloc functions, otherwise still have the problem. Try this:
n=malloc(sizeof(int));
*n=atoi(argv[1]);
Greetings
Upvotes: 0
Reputation: 134326
Both your code snippets invoke undefined behaviour, courtesy,
*n
argv[1]
(if argc
is not >=2
)Segmentation fault is one of the many side-effects of UB. UB case includes working seamlessly scenario, too.
Why the second with the fork works?
It has nothing to do with presence (or absence) of fork()
UB. TL;DR.
but using the fork() seems to do this automatically.
Visuals can be deceptive. Don't put your money on UB.
Upvotes: 4
Reputation: 223872
Because n
is uninitialized and therefore pointing to an unknown memory address, you are invoking undefined behavior. It might crash (as in the first example), or it might not (as in the second example).
In a situation like this something as simple as adding an unused variable can make a program crash that wasn't before, or vice versa.
Allocate memory for n
, and you won't have that problem.
Edit:
The fact that running ./test 100
works when you run the second program, no matter how many times, is a matter of luck. The fact that you added a call to fork
(in this case) just so happened to rearrange the way memory is laid out so that it would work. Later on you might decide to a a call to printf
for extra debugging and all of a sudden it starts crashing again.
Adding the fork
call didn't automatically allocate any space.
The only way to prevent a crash is to allocate memory for n
, and to ensure that argc
is at least 2 so that argv[1]
points to someplace meaningful.
Upvotes: 3
Reputation: 14688
It does not work. (Or more precisely, you have undefined behavior)
1) The fork is just hiding the segfault, because you are not checking the exit code of the child process.
2) The allocation of memory is not automatic -- ever !
You are just writing to a random location, and you may just be "lucky" that in the second version that the random location is within your process space.
Upvotes: 7