Reputation: 1
For the purposes of an exercise, I was given a snippet of code and told to find the bug. I removed a bunch of noise and the part that is tripping me up is the following:
int main() {
char *p;
char n;
scanf("%i", n);
if (n < get_int()) {
p = malloc(n);
}
}
Here, if I enter a number for n
, I get a seg fault. If I enter a character, n
is set to 0
. What is scanf
doing that makes this so?
Edit: the exercise I'm trying to figure out is Exercise 2 from this page
Upvotes: 0
Views: 68
Reputation: 1631
You aren't just passing the wrong kind of variable to scanf, you are also passing it's value instead of the pointer to it. The scanf have no way of knowing this value isn't an actual pointer to store the scanned data into, so thats exactly what its going to try and do, scan the input and place it into whatever memory address the n, treated as pointer value, happened to point to. In the absolute most of the cases this will attempt to access unmapped/protected/etc memory, and cause segfault/access violation.
Entering a character simply terminates the scan prematurely, avoiding the segfault, and leaving the n intact. Bit since the value of n isn't initialized, it can happen to be just about anything, any junk that happened to be on the stack at that point of time.
Upvotes: 0
Reputation: 153358
It is simply UB.
C does not specify any specific behavior here. "%i"
expect a int *
, not an uninitialized char
converted to an int
.
"What is scanf doing that makes this so?" implies defined behavior. There is no specified UB.
"If I enter a character, n is set to 0. " --> scanf()
does not attempt to change n
, it uses a copy of n
(passed by value).
The usual scanf()
usages is like the below where the address of nn
is passed, not nn
itself.
int nn;
if (scanf("%i", &nn) == 1) Success();
else Failure();
Upvotes: 1