Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
376 views
in Technique[技术] by (71.8m points)

c - char array in structs - why does strlen() return the correct value here?

I have a simple program like this:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct 
{
    int numberOfDays;
    char name[10];
} Month;


int main(void) 
{
    const Month months[12] = { 
        { 31, {'J', 'a', 'n'} },
        { 28, {'F', 'e', 'b'} }
    };

    printf("%zu
", strlen(months[0].name));
    printf("%zu
", sizeof(months[0].name));

    printf("%zu
", strlen(months[1].name));
    printf("%zu
", sizeof(months[1].name));

    return 0;
}

The output is like this:

3
10
3
10

I understand why sizeof(months[i].name) prints 10, but why does strlen return the correct value in this case?

My thought was, that strlen counts until the first '', but the char name[3] array is not null terminated. From my understanding this should be undefined behaviour? Does it only work by accident?

I'm wondering what the memory layout is in the above months[12] array.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

TL;DR Answer: No, this is well-defined behaviour.

Explanation: As per the C11 standard document, chapter 6.7.9, initalization,

If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.

In your case, you have a char array of 10 elements

 char name[10];

and you've supplied initializer for only 3 elements, like

{ 31, {'J', 'a', 'n'} },

So, the rest of the elements in name is initialized to 0 or ''. So, in this case, strlen() returns the correct result.

Note: Please do not rely on this method for null-termination of strings. In case, you're supplying the exact number of elements as initalizer, there will be no null-termination.


EDIT:

In case the name definition is changed to char name[3] and initialized with three chars, then , as per the note above, usage of strlen() (and family) will be undefined behaviour as it will overrun the allocated memory area in search of terminating null.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...