简体   繁体   中英

The null character at the end of string literal

I wrote two versions of codes to practice how to make a character array, and I was expecting the result to be the same.

version 1:

int main(void)
{
    char a[7] = "and";

    printf("size: %d   length: %d",sizeof(a), strlen(a) );
}

version 2:

int main(void)
{
    char a[7];
    a[1] = 'a';
    a[2] = 'n';
    a[3] = 'd';

    printf("size: %d   length: %d",sizeof(a), strlen(a) );
}

However, here is the result I got:

version 1:

size: 7   length: 3

version 2:

size: 7   length: 4

As far as I know, the string ends with null character, and null character in a string literal is implicit, but why did it disappear? Why didn't it be included as the last element as length in Version 1 shows 3?

In fact strlen is supposed to exclude the null character, so the output 3 is correct. The problem with the second version is that a[7] is not initialized so its values may be arbitrary. It just so happens in this case that the 5th value is 0 and the 0th is not, thus the output 4. Note that in the second version you use wrong indices - indexing of arrays starts from 0, not from 1.

If you want to make this work in the second version, re-write it like so:

int main(void)
{
    char a[7] = {0};
    a[0] = 'a';
    a[1] = 'n';
    a[2] = 'd';

    printf("size: %d   length: %d",sizeof(a), strlen(a) );
}

This initializes the first value in a to 0 explicitly and implicitly makes all other values zero too.

sizeof measure the memory size of something. strlen calculates the length of a c-string (length defined as the length of the sequence of characters excluding the nul terminating one). Here your c-string is shorter than the memory used to store it.

sizeof is C-operator evaluated as compile-time.

strlen is a library function, called at runtime.

strlen(3)

DESCRIPTION The strlen() function computes the length of the string s.

RETURN VALUES The strlen() function returns the number of characters that precede the terminating NUL character.

Beware that your second example is undefined as the character array is not initialized, strlen may overflow... You have no guarantee that non initialized chars are set to 0.

As per strlen description:

 size_t strlen(const char *str);

Returns the length of the given null-terminated byte string, that is, the number of characters in a character array whose first element is pointed to by str up to and not including the first null character. The behavior is undefined if str is not a pointer to a null-terminated byte string.

Since in the second version, a is not a null-terminated byte string, the behavior is undefined .

Note that assigning individual character literals to a char array does not make it a string literal, to create a properly null-terminated char array using that kind of assignment you need to do it yourself, starting at index 0 :

a[0] = 'a';
//...
a[3] = '\0';

In the second case

int main(void)
{
    char a[7];
    a[1] = 'a';
    a[2] = 'n';
    a[3] = 'd';

    printf("size: %d   length: %d",sizeof(a), strlen(a) );
}

you are lucky that

  • a[0] did not contain a 0 (ie, '\0' or null): you would have seen a value 0 as length.
  • a[4] actually had a null value, otherwise, your computer might have been burnt!!

In other words, for a local variable with automatic storage, if left uninitialized, the values are indeterminate. There's no guarantee of a 0-filling (which acts as null terminator), so using the array as a string (ex: argument to strlen() ) will likely have an effect of accessing out of bound memory and invoke undefined behavior .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM