I have been reading C Primer Plus (5th edition) by Stephen Prata. The Program listing 11.9 is a program to show what may the puts()
function do if we declare a string and assign a value without an ending null character. (Of course this is viewed as a grammar mistake, but I want to know what error will this bug cause.) I experimented on my computer (with CodeBlocks my ide) a similar program, and tried different ways to declare the string.
For the program
#include <stdio.h>
int main()
{
char a[]={'a','b','c','d'};
char b[100]="Stack Overflow";
puts(a);
return 0;
}
in which I used a[]
to declare the string, the program indeed output some thing other than abcd
. I tried several times, and it always output abcd<
and an empty line:
output:
abcd<
If I declare the string by a[100]
, i.e. the program
#include <stdio.h>
int main()
{
char a[100]={'a','b','c','d'};
char b[100]="Stack Overflow";
puts(a);
return 0;
}
Then it seems quite normal. The program always output abcd
and an empty line after I have repeated several times:
output:
abcd
If I use the pointer to declare the string:
#include <stdio.h>
int main()
{
char *a={'a','b','c','d'};
char b[100]="Stack Overflow";
puts(a);
return 0;
}
Then it only output an empty line:
output:
Why different ways of declaring the string, which is assigned a value without an ending '\0'
yields different outputs?
char a[100]={'a','b','c','d',};
If an aggregate (an array or structure) is explicitly initialized but not completely, the elements or members without initializers are implicitly initialized the same way as objects with static storage duration (per C 2018 6.7.9 21). For char
elements, that means they are initialized to zero (per 6.7.9 10). So, after a[0]
through a[3]
are initialized with the given character codes, a[4]
is initialized to zero. So the string beginning at the start of a
is null terminated, by the null character in a[4]
, and passing that string to puts
prints a string in the ordinary way.
char *a={'a','b','c','d',};
This is not a proper way to initialize a
. {'a','b','c','d',}
does not represent an array; it is a list of initial values. Since a
is declared as a pointer, it should be initialized with a single value that is a pointer.
When you compiled this, the compiler warned you that 'a'
was the wrong type to initialize a
, and it warned you there were excess initializers in the list.
When the compiler proceeded after this warning, it converted 'a'
to a pointer, which typically yields an invalid address. It is surprising that puts(a)
did not cause the program to crash in attempting to access that address. (Perhaps you are running in a GUI, saw an empty output window, and did not notice a separate message about the program crashing?) If the program did not crash, there could have been a zero byte at the address a
was initialized with, so passing a
to puts
printed nothing.