0

Consider the case:

char s1[] = "abc";
s1[3] = 'x';
printf("%s", s1);

As I know, printf prints characters until it finds the null character and then stops.

When I overwrite the null character by 'x', why does printf print the s1 array correctly? How does it find the null character?

ryanpattison
  • 6,151
  • 1
  • 21
  • 28
Higgs
  • 63
  • 2
  • 8
  • 2
    Be careful to distinguish between an *array* (where each element can hold any value) and a C-string (which, per definition, ends at the first `0` code). Your code transforms an array which happens to form a valid C string into a not-a-valid C string. – Jongware Jun 27 '15 at 15:41

4 Answers4

5

Your printf call invokes undefined behaviour because s1 doesn't have zero (aka null byte) terminator. s1 is an array of 4 characters and over writing the null byte is not an issue. After

s1[3] = 'x';

s1 will become:

[a][b][c][x]

But you can't print it as a string. A string in C is, by definition, a sequence of bytes terminated with a null byte. It just happens to work this time but you should never rely on that.

P.P
  • 117,907
  • 20
  • 175
  • 238
2

It means only that after this array there is by accident a null character in the memory.:)

You can try the following example

char s0[] = "xxx";
char s1[] = "abc";
char s2[] = "yyy";
s1[3] = 'x';
printf("%s",s1);

and see the result.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
2

The printf function will print all the characters untill it encounters a nul character.

In your case, you have started accessing beyond the memory that was allocated and accessing memory beyond what is allocated is undefined behavior

In this case it accidently happen to be nul.

Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97
Pradheep
  • 3,553
  • 1
  • 27
  • 35
0

If it printed "abcx". It means that there was already a null in s1[4]. The value on the stack depends on previous operations. So it may always be a zero in that position but what is more likely to happen is that there is a zero while you are debugging the code and nothing goes wrong, but then in release a zero is not put in that position and you end up with a difficult bug to debug.

Undefined by the language definition does not mean undefined in an implementation. eg MS Visual Studio when compiling in Debug mode will set memory to predictable values to aid debugging. When and why will an OS initialise memory to 0xCD, 0xDD, etc. on malloc/free/new/delete?

Community
  • 1
  • 1
QuentinUK
  • 2,997
  • 21
  • 20
  • This is correct, but the truth is that the code invokes undefined behavior, so [this](http://stackoverflow.com/a/31090416/1983495) a more concrete answer because when undefined behavior happens one of the possible things is that it works without problems, I don't say as expected because you can't expect a given behavior. – Iharob Al Asimi Jun 27 '15 at 15:42
  • It is undefined by the language definition but it can be defined in an implementation, it can also be predictable in an implementation, or in a particular compiled program when running with the same data repeatedly. – QuentinUK Jun 28 '15 at 00:45