biscuitduke
biscuitduke

Reputation: 1

What does scanf do when passing a char and an integer specifier?

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

Answers (2)

Boris Lipschitz
Boris Lipschitz

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

chux
chux

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

Related Questions