Let's consider this two lines:
char input[1];
gets(input);
Let's say the input is "test". printf("%s\n",input) => "test" but if i use the debugger i see input[0]='t' no input[1]... What exactly happens?
Let's consider this two lines:
char input[1];
gets(input);
Let's say the input is "test". printf("%s\n",input) => "test" but if i use the debugger i see input[0]='t' no input[1]... What exactly happens?
You overflow your buffer, that's what happens. You're writing to memory that isn't yours and getting lucky.
That's a buffer overflow, fyi. For fun add char untouched[20];
after char input[1];
and also print untouched
. Don't use gets()
, use fgets()
or something else with bounds checking.
The debugger doesn't show input[1]
because there is no such thing. Your char input[1];
declaration allocates an array of length 1, not an array from 0 to 1.
This:
char input[1];
only reserves one character's worth of memory, but then you put five characters in.
The debugger knows you've only got one character, and will show you just what it knows you have.
The running program will splatter the string over whatever memory is adjacent to input
and either crash or get away with it. In your case you're getting away with it.
You declare an array with the fixed size '1'. The index of the first element in the array is always '0'. Thats why input[0] holds the char 't'.
EDIT - The rest is stored somewhere outside the buffer (BufferOverFlow).
A char[] of length n has the last entry stored in position n-1. So,
char input[1];
means a single char type data stored in the array input, position 0.
(edited to provide some clarification - first wording was too bad.)
gets(s) reads a line from stdin into the buffer pointed to by s until either a terminating newline or EOF, which it replaces with '\0'. No check for buffer overrun is performed
http://linux.die.net/man/3/gets
When you execute gets, input is written into the buffer pointed by s. Then it adds a \0. Only the 't' is inside the input buffer. The rest, is located on contiguous memory on the stack. printf prints "test", because its what it can read starting at s up to the first \0. But the "est\0" are outside the buffer.
------
| t | input - Debugger only sees this position.
------
| e | Memory you are stepping onto. Trouble if it doesn´t belong to your proc.
| s |
| t |
| \0 |
------
When you debug it, input only points to one char, so that's all you can see.
Its important to take a look at the "No check for buffer overrun is performed". This means that gets function doesn't really care if you have allocated memory for your input. It will just start copying all of it from the point you indicate. If you are not careful, then your input can step onto important information. On some of the worst case, this will be the return address for your function (where you are using gets). Someone who "just makes" this mistake, will say "wtf is going on". Someone who intentionally does that, will point your return address to a specific part, and execute code located there.