0

Given this struct

struct node {
    struct node* next;                              
    union {
        int lockId;
        pthread_t threadId;
    } id;
};

What is the correct way to initialize a dynamic array using malloc/realloc to store pointers to this struct?

I have tried:

struct node* nodes = (struct node*)malloc(n * sizeof(struct node*));

but I when compiling I get an error saying: initializer element is not constant

even though I am using #define MAXNODES 10 As for now, I am currently using a static array (fixed-size) by doing:

node *(nodes[MAXNODES]);

Any help would be greatly appreciated!

igohardinmath
  • 43
  • 1
  • 5
  • Possible duplicate of [Error "initializer element is not constant" when trying to initialize variable with const](https://stackoverflow.com/questions/3025050/error-initializer-element-is-not-constant-when-trying-to-initialize-variable-w) – swapgs Nov 02 '18 at 15:49
  • Just to make sure you get this; your specific `malloc` call will only store enough bytes to store `n` pointers to node structs, not allocate memory for `n` node structs. Given that, is that what you intended? (Also remove the cast for malloc) – Jite Nov 02 '18 at 16:02
  • @Jite yep just the pointers to the node struct ~ – igohardinmath Nov 02 '18 at 16:05
  • 1
    please show the actual code and the actual error message. – pm100 Nov 02 '18 at 16:19
  • `nodes = malloc(sizeof *nodes);` is a simply alternative to `nodes = (struct node*)malloc(n * sizeof(struct node*));` – chux - Reinstate Monica Nov 02 '18 at 16:34
  • do we need the asterisk at the end of node in (struct node*)malloc(sizeof(struct node) * n) ? – igohardinmath Nov 02 '18 at 18:45

1 Answers1

0

There is no problem with your data struct here, using an Union or not doesn't matter. Your problem comes from the fact that the syntax for creating arrays is not correct.

In the following you can see how to create both dynamic and static arrays:

#include <stdlib.h>
#include <pthread.h>

#define MAX_NODES 10

struct node {
  struct node *next;
  union {
    int         lockId;
    pthread_t   threadId;
  } id;
};

int main()
{
  struct node nodes_static[MAX_NODES];

  int n = MAX_NODES;
  struct node* nodes_dynamic = (struct node*)malloc(sizeof(struct node) * n);
}

Please also note, that it is good practice to verify the return value of a dynamic allocation and that the dynamic memory should be freed after use.

Tezirg
  • 1,629
  • 1
  • 10
  • 20
  • so if i want to access the fields in the first element in nodes_dynamic I would have to do something like: nodes_dynamic[0]->next ? EDIT: great! thank you dude! – igohardinmath Nov 02 '18 at 16:15
  • given that new_node was malloc(ed), to add would be: nodes[n] = new_node? – igohardinmath Nov 02 '18 at 16:26
  • @igohardinmath No, this example (`nodes_dynamic`) actually creates storage for `n` number of `struct node`'s. As you've created an array of nodes (`nodes_static`), you don't need to create another array for pointers to it, just use `&nodes_static[index_you_want]`. There's no need to have a `next` variable (linked list) in the struct if you're doing it the above way. What it sounds like you want is just `struct node *start_node = calloc(1, sizeof(*node_a))` and then just `struct node *second_node = calloc(...)` and `start_node->next = second_node`. (Can skip the middle storage, just for edu) – Jite Nov 04 '18 at 20:55