Q:

Am I erasing the stack here?

I am using gcc on Linux and the below code compiles successfully but not printing the values of variable i correctly, if a character is entered once at a time i jumps or reduces to 0. I Know I am using %d for a char at scanf(I was trying to erase the stack). Is this a case of attempt to erase stack or something else ?( I thought if the stack was erased the program would crash).
#include <stdio.h>

int main()
{
    int i;
    char c;

    for (i=0; i<5; i++) {
        scanf ("%d", &c);
        printf ("%d ", i);
    }
    return 0;
}

A:

With your scanf(), you are inserting a int inside a char.  One char is usually stored using just 1 byte, so your compiler will probably overflow, but it could or not overwrite other values, depending on the alignment of the variables.
If your compiler reserves 1 byte for the char, and the memory address of the int is just after the address of the char (that will probably be the case), then your scanf() will just overwrite the first bytes of i.  If you are in a little-endian machine and you enter values smaller than 256, then i will always be 0.
But it can grow larger if you enter a bigger value.  Try entering 256; i will become 1.  With 512, i will become 2, and so one.
But you are not "erasing the stack", just overwriting some bytes (in fact, you are overwriting sizeof(int) bytes; one of them correspond to the char and the others will probably be all the bytes in your int but one).
If you really want to "erase the stack", you could do something like:
#include <string.h>

int
main(void) {
    char c;

    memset(&c, 0, 10000);

    return 0;
}

A:

Besides the arguments to main, you have an int and a char on the stack.
Lets assume sizeof(int) == 4 and only have a look at i and c.
(              int i               )(char c )
[   0   ][   1   ][   2   ][ 3 (&i)][ 4 (&c)]

So this is actually your stack layout without argc and *argv.
With i consuming four times more memory than c in this case.
The stack grows in the opposite direction, so if you write something bigger than a char to c, it will write to [4] and further to the left, never to the right. So [5] will never get written to. Instead you overwrite [3].
For the case where you write an int to c and int is four times bigger than c, you'll actually write to [1][2][3][4], just [0] will not be overwritten, but 3/4 of the memory for the int will be corrupted.
On a big-endian system, the most significant byte of i will be stored in [3] and therefore get overwritten by this operation. On a little-endian system, the most significant byte is stored in [0] and would be preserved. Nonetheless, you corrupt your stack this way.
As ams mentions this is not always true. There could be different alignments for efficiency or because the platform only supports aligned access, leaving gaps between variables. Also a compiler is allowed to do any optimizations as long as it has no visible side-effects as stated by the as-if rule. In this case the variables could perfectly be stored in a register and never be saved on the stack at all. But a lot of other compiler optimizations and platform dependencies can make this way more complex.
So this is only the simplest case without taking platform dependencies and compiler optimizations into account and also seems to be what happens in your special case with maybe some minor differences.

A:

@foobar has given a very nice description of what one compiler on one architecture happens to do. He(?) also gives an answer to what a hypothetical big-endian compiler/system might do.
To be fair, that's probably the most useful answer, but it's still not correct.
There is no rule that says the stack must grow in one way or the other (although, much like whether to drive on the left or the right, a choice must be made, and a descending stack is most common).
There is no rule that says the compiler must layout the variables on the stack in any particular way. The C standard doesn't care. Not even the official architecture/OS-specific ABI cares a jot about that, as long as the bits necessary for unwinding work. In this case, the compiler could even choose a different scheme for every function in the system (not that it's likely).
All that is certain is that scanf will try to write something int-sized to a char, and that this is undefined. In practice there are several possible outcomes:

It works fine, nothing extra is overwritten, and you got lucky. (Perhaps int is the same size as char, or there was padding in the stack.)
It overwrites the data following the char in memory, whatever that is.
It overwrites the data just before and/or after the char. (This might happen on an architecture where an aligned store instruction disregards the bottom bits of the write address.)
It crashes with an unaligned access exception.
It detects the stack scribble, prints a message, and reports the incident.

Of course, none of this will happen because you compile with -Wall -Wextra -Werror enabled, and GCC tells you that your scanf format doesn't match your variable types.

