Home > Mobile >  How do I initialize an array of pointers to structures in C?
How do I initialize an array of pointers to structures in C?

Time:07-21

I am attempting to create an array of pointers to structs. I would like each of the structs to have the same values on initialization, but not the same pointers to them.

Currently I am attempting to do it like this:

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

struct Node {
    float value;
    bool evaluated;
    struct Node* children[10];
};

void main() {
    int i;

    struct Node* node = &(struct Node) {
        .value = 0,
        .evaluated = false,
        .children = { 0 }
    };

    for (i = 0; i < 10; i  ) {
        node->children[i] = &(struct Node) {
            .value = 0,
            .evaluated = false,
            .children = { 0 }
        };
        printf("Index: %d, pointer: %p\n", i, node->children[i]);
    }
}

Unfortunately, this gives me these results:

Index: 0, pointer: 00DEF640
Index: 1, pointer: 00DEF640
Index: 2, pointer: 00DEF640
Index: 3, pointer: 00DEF640
Index: 4, pointer: 00DEF640
Index: 5, pointer: 00DEF640
Index: 6, pointer: 00DEF640
Index: 7, pointer: 00DEF640
Index: 8, pointer: 00DEF640
Index: 9, pointer: 00DEF640

Is there any way I could produce this in such a way as to give the same results, but with different pointers to each of the structs?

CodePudding user response:

A compound literal has a lifetime of the block it is declared in. So after each iteration of the for loop the literal no longer exists and therefore the pointer to it is invalid, and using such a pointer triggers undefined behavior

Rather than using compound literals, you should allocate memory dynamically for each instance. And since you're initializing the members with all zero values, you can use calloc to return zero-initialized memory.

struct Node* node = calloc(1, sizeof(struct Node));

for (i = 0; i < 10; i  ) {
    node->children[i] = calloc(1, sizeof(struct Node));
    printf("Index: %d, pointer: %p\n", i, node->children[i]);
}

CodePudding user response:

When you use a compound literal, the lifetime of the object is the containing block. When you do this in a loop, the lifetime of each array element ends when the loop iteration completes. So these pointers become invalid.

You need to use dynamic allocation with malloc() to create multiple array elements. You can then copy into the allocated memory by assigning from the compound literal.

There's no need to use a compound literal for the top-level node, you can just use an ordinary local variable there.

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

struct Node {
    float value;
    bool evaluated;
    struct Node* children[10];
};

void main() {
    int i;

    struct Node node = {
        .value = 0,
        .evaluated = false,
        .children = { 0 }
    };

    for (i = 0; i < 10; i  ) {
        node.children[i] = malloc(sizeof *node.children[i]);
        *(node->children[i]) = (struct Node) {
            .value = 0,
            .evaluated = false,
            .children = { 0 }
        };
        printf("Index: %d, pointer: %p\n", i, node->children[i]);
    }
}
  • Related