7

I have the following struct:

 struct node {
    int data;
    struct node *next;
};


struct node *n1 = malloc(sizeof(struct node));

I am not sure how initialize all the pointer fields of struct pointer to NULL without causing any potential for memory leaks?

22
  • 6
    By using calloc instead of malloc. Commented Jan 23, 2016 at 1:11
  • 2
    What's wrong with n1->next = NULL; ? Commented Jan 23, 2016 at 1:11
  • 1
    @WeatherVane: that will work with current processors, but it is not strictly correct. Commented Jan 23, 2016 at 1:18
  • 2
    If you don't like calloc, you can follow your malloc call with a memset, which would accomplish the same thing. Commented Jan 23, 2016 at 1:18
  • 1
    @WeatherVane: this is a tricky one: it has value 0 in the sense that NULL == 0 is true, but its representation might not be all bits zero. I don't know of any CPU where it is not, but the Standard allows it. Commented Jan 23, 2016 at 1:25

2 Answers 2

7

You need to initialize the members of the structure after you allocate it with malloc:

struct node {
    int data;
    struct node *next;
};

struct node *n1 = malloc(sizeof(struct node));
n1->data = 0;
n1->next = NULL;

If you want to initialize your structure in one step with default values, which can be handy if it is much larger, use a static structure with these defaut values:

struct node def_node = { 0, NULL };

struct node *n1 = malloc(sizeof(struct node));
*n1 = def_node;

Alternately, you can use the C99 syntax:

struct node *n1 = malloc(sizeof(struct node));
*n1 = (struct node){ 0, NULL };

As commented by Leushenko, you can shorten the initializer to { 0 } for any structure to initialize all members to the appropriate zero for their type:

struct node *n1 = malloc(sizeof(struct node));
*n1 = (struct node){ 0 };
Sign up to request clarification or add additional context in comments.

2 Comments

I was looking for a way to make the entire n1 NULL. For example : n1= {0,NULL}; I dont want to go variable by variable. I want to set all of n1 to NULL at once.
The advantage of this is that any fields you leave out of the struct you use to initialize the value will be automatically set to the appropriate zero value for that type, so this is very maintainable: just write one field (can't have an empty literal), and the others will take care of themselves.
3

You have four choices:

1) Set the pointers manually, e.g. node-> next = NULL;

2) Use calloc() to zero out the memory when you allocate it

3) Use memset() to zero out the memory after you've allocated it.

... OR ...

4) Don't worry about explicit initialization until you actually need to use the struct. Design your program such that you make sure any pointer is assigned before you try to read it.

FYI, this is one of the main purposes of a "constructor" in OO languages like C++ or C#: to initialize "class invariants".

PS:

5) I forgot about C99 struct initialization, which Leushenko mentioned:

what is the difference between struct {0} and memset 0

struct A
{
    int x;
    int y;
};
...
A a = {0};

This is vastly preferred to either calloc() or memset().

It also applies to other initialization values besides "0":

C99 Standard 6.7.8.21

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.

4 Comments

Someone is going to come here and say that calloc() and memset() are not guaranteed to set pointers to NULL, which is technically true, but to them, I preemptively say that systems where it doesn't work are so impossibly rare that we simply don't care about them.
@Dietrich Epp: you're absolutely correct. These links explain further: c-faq.com/null, stackoverflow.com/questions/9894013/is-null-always-zero-in-c. You're also correct that calloc() and memset() are OK in just about every imaginable circumstance. The main reason one wouldn't use them is "performance" - the (miniscule!) overhead of assigning memory whether actually need to or not.
@DietrichEpp: I already did in comments above, but agree it is a moot point. Thank you paulsm4 for the link.
A better reason to not use them is because it's inelegant to use a function over void * when the language provides primitive builtins that do the same job. For non-arrays, there's literally no reason to ever use calloc.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.