1

The following code reads up to 10 chars from stdin and output the chars.
When I input more than 10 chars, I expect it to crash because msg has not enough room, but it does NOT! How could that be?

 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>

 int main(int argc, char* argv[])
 {
     char* msg = malloc(sizeof(char)*10);
     if (NULL==msg)
         exit(EXIT_FAILURE);
     scanf("%s", msg);
     printf("You said: %s\n", msg);
     if (strlen(msg)<10)
         free(msg);
     return EXIT_SUCCESS;
 }
adamsmith
  • 5,759
  • 4
  • 27
  • 39
  • try using `scanf("%9s", msg)` to scan when you have a char array of length 10. (Leave 1 char for the string termination char `'\0'`) – ffledgling Oct 30 '13 at 12:37

5 Answers5

3

Use fgets instead, scanf is not buffer safe. What you are seeing is Undefined Behavior.

Sadique
  • 22,572
  • 7
  • 65
  • 91
0

You may allocate "safe" big size when using scanf(). On user input it should be 2 lines (cca. 2x80 chars), in case of files some bigger.

Conclusion: scanf() is kinda quick-and-dirty stuff, don't use it in serious projects.

ern0
  • 3,074
  • 25
  • 40
0

You can specify max size in scanf() format string

scanf("%9s", msg);
Benoit Blanchon
  • 13,364
  • 4
  • 73
  • 81
0

I would imagine that malloc() allocates blocks of memory aligned to word boundaries. On a 32-bit machine, that means whatever you ask for will be rounded up to the nearest multiple of 4. That means you might get away with a string of at least 11 characters (plus a '\0' terminator) without suffering any problems.

But don't ever assume this to be the case. Like everyone else is saying, you should always specify a safe maximum length in your format string if you want to avoid problems.

r3mainer
  • 23,981
  • 3
  • 51
  • 88
  • Actually i entered far more than 10 chars, which i think is beyond word boundaries, and the program didn't complain. – adamsmith Oct 30 '13 at 12:52
  • It won't ever complain, it will just crash at some point. If you have other variables defined in your program, you might find their values are doing strange things. You might find this interesting: http://stackoverflow.com/questions/19559133/conflict-between-a-stanford-tutorial-and-gcc – r3mainer Oct 30 '13 at 12:57
0

It does not crash because c is very lenient, contrary to popular belief. It is not required for the program to crash or even complain if a buffer is overflown. Say you define

union{
 uint8_t a[3]
 uint32_t b
}

then a[4] is perfectly fine memory and there is no reason to crash (but don't ever do this). Even a[5] or a[100] may be perfectly fine. On the other hand I may try to access a[-1] which happens to be memory the OS does not allow you to access, causing a segfault.

As to what you should do to fix this:as others have pointed out, scanf is not safe to use with buffers. Use on of their suggetsions.

R.Deckers
  • 71
  • 2