This question already has an answer here:
How is an array stored in memory in this program? What happened here? How to understand this behaviour in c?(is it undefine/unspecified/implementation behaviour).
#include <stdio.h>
int main()
{
char a[5] = "world";
char b[16] = "haii how are you";
printf("string1 %s\nstring2 %s\n", a, b);
return 0;
}
output:
user@toad:~$ gcc -Wall simple.c
user@toad:~$ ./a.out
string1 world
string2 haii how are youworld
user@toad:~$
but it is work fine.
char a[5] = "world";
char b[17] = "haii how are you?";
First notice that your program is undefined behavior as you call
printf
with a char array and not a string since there isn't room for the zero-termination in the two arrays. For instance you only reserve 5 chars fora
andworld
takes up all 5, i.e. no room for the termination.A strict person would say that due to UB it makes no sense to speculate about what is going on - with UB anything can happen.
But if we do it anyway then it is likely as described below.
The answer would depend on your system as
c
doesn't specify all aspects of storing data. It is specified that an array must be in contiguous memory but exactly how and where that memory is located, is beyond the standard.From the output you have, it seems that your system have located it like this:
You can't know what is after the last
d
.However, when you print
a
you get the outputworld
which tells us that "by luck" there is a '\0' just after the lastd
.So printing
a
will giveworld
and printingb
will givehaii how are youworld
.Your code should be:
to make room for the termination of each string and so that your memory layout would be
Notice: The '\0' that you got "by luck" is probably because your system initializes all memory assigned to your program to zero at start up.
The code is not correct. Some compilers do not want to compile it:
Maybe your compiler just ignores array size, assigning the address of string constant to it and keeping null character at the end.
As already mentioned by others, while the array declaration itself is completely conformant (you declare an array of chars, not a string):
(Section 6.7.8/14 of C99 standard n1256.pdf; thanks to @Michi for pointing out the paragraph)
Trying to print these using
%s
is undefined though. However you can specify the length of characters to print in the format string (%.5s
) -- this way you'd be ok again.Concerning the memory layout: C does not make many promises about how the memory is laid out actually. The only thing I can find is:
(Section 6.2.5/20 of C99 standard n1256.pdf)
Note however, that in C++ even the code
is illegal:
(Section 8.5.2/2 of C++ 14 standard n4296.pdf)
Both of the string in the first snippet is not null terminated. They are just character arrays, not null terminated string literals.
printf
with%s
specifier expects a null terminated string as its argument. Passing wrong type of argument will invoke undefined behavior.printf
write the string to the standard output till it encounters a'\0'
character. In case of absence of'\0'
it will read past the array. Sincea
andb
are not null terminated, it could be the case that after writingb
to the terminalprintf
continues to search for'\0'
and it founds it after the stringa
.As per the C11 standard (6.7.9 Initialization).
As per this for you
At the end of the "world" and "haii how are you" the '\0' is not added. So while using printf it searches for '\0' and prints both 'a' and 'b'.
World has 5 characters inside and if you initialize it, you must indicate that your string is ended by null character --> \0
If you define it like that
Then compiler put the null character at the end for you.
For your question, most compilers don't allow you define
char a[5] = "world"
but it seems that your memory is allocated like this[ h ] [ a ] [ i ] [ i ] [ ] [ h ] [ o ] [ w ] [ ] [ a ] [ r ] [ e ] [ ] [ y ] [ o ] [ u ] [ w ] [ o ] [ r ] [ l ] [ d ] [ \0 ]
Then last point you must know that %s prints the character set until it reaches null character --> \0