4
int main(void)
{
    char name1[5];
    int count;
    printf("Please enter names\n");
    count = scanf("%s",name1);
    printf("You entered name1 %s\n",name1);
    return 0;
}

When I entered more than 5 characters, it printed the characters as I entered, it was more than 5, but the char array is declared as:

char name1[5];

Why did this happened

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
user2556058
  • 311
  • 4
  • 9
  • 7
    This is undefined behavior, anything can happen including a program that seems to work. – Shafik Yaghmour Jul 15 '13 at 14:57
  • Try to enter a very large string. Your program is very likly to crash because it will overwrite the return address of the main function on the stack. – typ1232 Jul 15 '13 at 14:59
  • Ever wondered how computer break-ins happen? Your program shows one side of the "how". The other side is explained [in an article on Stack Buffer Overflow](http://en.wikipedia.org/wiki/Stack_buffer_overflow). – Sergey Kalinichenko Jul 15 '13 at 15:03
  • 1
    Read: [Reading a line using scanf() not good?](http://stackoverflow.com/questions/17294809/reading-a-line-using-scanf-not-good) – Grijesh Chauhan Jul 15 '13 at 15:04
  • 3
    Possible duplicate of [How could it be possible to read and write past the array](http://stackoverflow.com/questions/17413252/how-could-it-be-possible-to-read-and-write-past-the-array). – haccks Jul 15 '13 at 15:08

6 Answers6

12

Because the characters are stored on the addresses after the 'storage space'. This is very dangerous and can lead to crashes.

E.g. suppose you enter name: Michael and the name1 variable starts at 0x1000.

name1: M       i     c      h      a      e      l     \0
      0x1000 0x1001 0x1002 0x1003 0x1004 0x1005 0x1006 0x1007
      [................................]

The allocated space is shown with [...] This means from 0x1005 memory is overwritten.

Solution:

Copy only 5 characters (including the \0 at the end) or check the length of the entered string before you copy it.

Michel Keijzers
  • 15,025
  • 28
  • 93
  • 119
6

This is undefined behavior, you are writing beyond the bounds of allocated memory. Anything can happen, including a program that appears to work correctly.

The C99 draft standard section J.2 Undefined Behavior says:

The behavior is undefined in the following circumstances:

and contains the following bullet:

An array subscript is out of range, even if an object is apparently accessible with the given subscript (as in the lvalue expression a[1][7] given the declaration int a[4][5]) (6.5.6).

This applies to the more general case since E1[E2] is identical to (*((E1)+(E2))).

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
2

This is undefined behavior, you can't count on it. It just happens to work, it may not work on another machine.

To avoid buffer overflow, use

fgets(name1, sizeof(name1) - 1, stdin);

or in C11

gets_s(name1, sizeof(name1) - 1);
Yu Hao
  • 119,891
  • 44
  • 235
  • 294
2

another example to make things clearer :

 #include <stdio.h> 

 int array[5] ;

 int main ( void )
 {

  array[-1] = array[-1] ; // sound strange ??

  printf ( "%d" , array[-1] ) ; // but work !!
  return 0 ;
 }

array in this case in an address, and you get number before or after that address, but this is undefined behavior unless you know what you do. Pointer works with ++ or -- !

1

It's very clear from other answers that this constitutes some kind of vulnerability to your program.

What can be learned from this? Lets assume:

 int func(void) 
{
 char buffer[1];
 ...

In almost every implementation of the C compiler, the code generated here will create a local stack area and enables you to access this stack by the address given in buffer. On this stack reside other important data too, for example: the address of the next code line to be executed after the function returns to it's caller.

You could, therefore, theoretically:

  • Enter a lot of code into your input function,
  • Create a code that defines (in binary code) a new function that does something ugly,
  • Overwrite the correct return address (on the stack) with the address that the new function would have if you write it beyond the buffers bounds.

This is called buffer overflow exploit, you can read up here (and on many other places).

rubber boots
  • 14,924
  • 5
  • 33
  • 44
1

Yes it is allowed in C, as there is no bound checking.

Raju
  • 1,149
  • 1
  • 6
  • 19