0
#include<stdio.h>
int main()
{
    char name[1];
    scanf("%s",name);
    printf("%s",name);
}

I am able to read a string of any size with this declaration

  • 10
    undefined behaviour. It might work or it might not work. – Rishikesh Raje Nov 09 '18 at 09:11
  • 1
    Are you suggesting that all arrays should be of length 1 because nothing bad happened on this occasion? You are quite wrong that the program will work with "any length string". Don't forget that the `scanf` will stop at the first whitespace, so your string may have been only a few bytes in length. – Weather Vane Nov 09 '18 at 09:13
  • 4
    In reality, it does not works fine : it is just that you do not see the effects of what goes wrong. – Joël Hecht Nov 09 '18 at 09:20
  • If you run it using Valgrind or GDB, you see there are some errors (memory errors). If you were to process `name` further, you'd very probably get a **Segfault**. – Jean-Marc Zimmer Nov 09 '18 at 09:34
  • 1
    "I went to a busy intersection. The light was red. I crossed the street anyway. It went absolutely fine." Does that mean crossing an intersection against a red light is okay? – Steve Summit Nov 09 '18 at 12:10

2 Answers2

3

Firstly, This is undefined behaviour. What happens in this case is unpredictable.

However, I will give an extra example of code with an additional variable to show what can go wrong with this approach.

int main()
{
    char name[1];
    int a=1;
    printf ("a = %d\n",a);
    scanf("%s",name);
    printf("%s\n",name);
    printf ("a = %d\n",a);
}

This is your original program with an additional variable, a and it is initialized to 1 and not changed.

Output

a = 1
aaaa
aaaa
a = 6381921

As you can see the value of a was changed by entering a large string.

Rishikesh Raje
  • 8,556
  • 2
  • 16
  • 31
  • Even that is unpredictable as there is no guarantee to the order in which the variables are allocated on the stack. If **a** happens to be at a lower address than **name**, the value of **a** will remain unchanged, but the the array overrun will smash the stack above it. – GermanNerd Nov 09 '18 at 10:52
  • @GermanNerd - agreed. This is just an example on **my** machine – Rishikesh Raje Nov 09 '18 at 10:54
0

For those new to C, I want to explain what is actually happening: In C, an array is a consecutive block of memory, represented by a pointer to the first cell of that array (first byte of the memory block).

Here is how it would look for array of char with one cell:

  6   7   8   9
+---+---+---+---+
| X | a | X | X |
+---+---+---+---+
      |__ name = 7

You have a byte of memory allocated somewhere and the variable name holds the address of this byte. It does not hold the length of the array, that information is only used to allocate it and then discarded.

When you call scanf it takes the address in name and starts filling the memory with user input. Since scanf has no information about the size, it will only stop in two cases: 1. End of the input 2. Error writing to memory

This is why it is impossible to tell what will happen, as it depends largely on the memory layout of the running program which in turn depends on the hardware, the OS and the compiler.

It also depends on the length of the input.

In this simplified example, scanf will keep writing to addresses 8, 9 and beyond. Assuming these addresses can be written to by your program, it will replace whatever is in there with user input.

printf will then read the memory starting at 7 (address in name) until it runs into a byte with value 0 and print everything to the screen.

If no other code was using that memory between call to scanf and call to printf the input data will still be there and will be printed correctly to the screen.

If however, there was code using those memory addresses, it could overwrite the input or crush the program because it read wrong data from memory.

Lev M.
  • 6,088
  • 1
  • 10
  • 23