I have two programs. Both initialize an array from a string literal. In one case the array size is exactly the number of characters I want to place in the array.
I wonder why the output of the size returned by strlen()
differs for both prorgams. Is it because of the terminating null character is missing? If so, then why is the output 16?
#include<stdio.h>
#include<string.h>
main()
{
char str[5] = "ankit";
printf("size of = %d \n ",sizeof(str));
int len = strlen(str);
printf("length = %d \n ",len);
}
output :- size of = 5 , length = 16
#include<stdio.h>
#include<string.h>
main()
{
char str[] = "ankit";
printf("size of = %d \n ",sizeof(str));
int len = strlen(str);
printf("length = %d \n ",len);
}
output :- size of = 6 , length = 5
In your first code, by writing
char str[5] = "ankit";
you don't have any space left for the null terminator to get stored, which is required to be there for str
to be used as a string . So, in that case, strlen()
invokes undefined behavior by overrunning the allocated memory in search of the null terminator.
OTOH, in the second snippet,
char str[] = "ankit";
you leave the size allocation to the compiler and it allocates memory for the elements in the string literal used as initializer plus the null terminator. So, you got the desired result.
IMO, always use the later approach, saves a lot of headache from time to time.
Your char[5]
is too short to hold the values "ankit"
.
As you say yourself, there is \0
-termination at the end of a C-style string. That means, your string literal is actually internally represented as "ankit\0"
(where \0 is a single character).
Since the strlen()
-function does not find the \0
character, it's behavior is undefined.
That means, you need a char[6]
to represent your string.
By omitting the explicit length of the array, you let the compiler choose the size (through the initialization, which is known at compile-time). Therefore, the compiler allocates the correct size (6 chars).
Yes, it is because the array in the first example does not set aside enough space for the 0 terminator. Here's how strlen
basically works:
size_t strlen( const char *str )
{
size_t len = 0;
while( *str++ )
len++;
return len;
}
strlen
starts at the address of the first element in str
and "walks" down successive addresses until it sees a 0
-valued byte. Since strlen
doesn't know how big the array corresponding to str
actually is (all it gets is a pointer to the first element), it will keep going past the end of the array until it sees a 0
.
All strings are arrays of char
, but not all arrays of char
are strings; if there isn't a zero terminator, it isn't a string.
char str[5]
can at max take 4 chars in it with last extra byte should reserve for '\0' character. Hence its undefined behavior.