1

I have a problem when I'm initializing this structure :

struct node {
    int label;
    struct node *lchild;
    struct node *rchild;
}

int main(void) {
    struct node n1;
    n1.label = 1;

    return EXIT_SUCCESS;
}

The problem is my members lchild and rchild don't point to NULL.

I can resolve the problem by adding

n1.lchild = NULL;
n1.rchild = NULL;

But I don't understand why I need to do that?

5
  • So what do they point to instead? Commented Nov 4, 2015 at 8:52
  • @Arc676 If I print their address, I have something like that 0x2000000000000000 and 0x7fff7cbd0010. If I print their label member, I have a segmentation fault. Commented Nov 4, 2015 at 8:53
  • Is writing struct node n1 = { .lchild = NULL} also boring? Commented Nov 4, 2015 at 8:56
  • 1
    You create n1 on the stack; C makes no guarantees about the initial values of stack-allocated variables, and they can and usually will contain random garbage. If you want them to contain specific values, you'll have to take care of that yourself. You could declare a function to do this for you: struct node* initNode(struct node* newNode) - sets the fields to their proper initial values and returns the pointer to the same struct. Commented Nov 4, 2015 at 8:58
  • @szczurcio Thanks for your explanations, that could be a solution. Commented Nov 4, 2015 at 9:00

2 Answers 2

7

The members of an automatic storage object such as n1 do not get zero-initialized automatically (See C11 standard, 6.7.9.10). You have to do this yourself.

You can take care of this easily by suitably initializing n1:

struct node n1 = {1};

This will set the first member to 1 and will zero-initialize the rest, meaning the pointers get initialized to NULL. You can be more explicit if you wish:

struct node n1 = {1, NULL, NULL};

References:

From the C11 standard, 6.7.9 Initialization:

  1. 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.

And, previously in the same section,

  1. ... If an object that has static or thread storage duration is not initialized explicitly, then:
    — if it has pointer type, it is initialized to a null pointer;

(emphasis mine)

Sign up to request clarification or add additional context in comments.

13 Comments

The the null-pointer not necessarily is represented by 0s. So using memset() (or any other approach initialising with 0) might mostly work, but isn't portable.
@alk I didn't say anything about memset. But are you sure zero-initialization of a pointer type is not guaranteed to NULL initialize it?
Right, you didn't ,copypasta bs from my side. Sry!
= {1} is fine: N1570 6.7.9.21 "If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, ... , the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration."
And about static storage duration initialization: 6.7.9.10 "... And If an object that has static or thread storage duration is not initialized explicitly, then: — if it has pointer type, it is initialized to a null pointer; ..."
|
7

I don't understand why I need to do that

Because the compiler doesn't do it for you.

You could skip this in case you can make sure the members aren't read before having been written to.

3 Comments

Alright, I thought all members are initialized with their default value, so pointers with null value. I will write a function to initialise this struct.
There are no "default"-values on C. @mathieu_b
Trivial edit since I accidentally downvoted this! Have an upvote now.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.