Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do we have to malloc a struct?

Tags:

c

malloc

struct

Consider the following code:

struct Node {
    void* data;
    int ref;
    struct Node* next;
};
typedef struct Node* NodePtr;

I have found that I am getting segfaults whenever I try to do anything with NodePtr's fields. E.g.:

NodePtr node;
node->ref = 1;

So I allocated some space for the NodePtr, and now it seems to work fine. Why is this? My guess is that since node is just a pointer, it has no memory for its fields.

So I tried to initialize the NodePtr:

NodePtr node = {
    node->data = 0;
    node->next = NULL;
    node->ref = 0;
};

And well, I got this error:

error: expected â}â before â;â token

This boils down to four questions:

  1. If my guess is incorrect, why doesn't it work if I don't use malloc()?
  2. Why does my initialization not work?
  3. Would initializing a struct offer memory on the stack and solve my problem?
  4. If not, do I have an alternative to having to allocate memory for every struct I use?
like image 297
Spag Guy Avatar asked Oct 05 '14 20:10

Spag Guy


2 Answers

A struct can be allocated automatically, but you are using a pointer to struct which will not allocate space for the destination struct. So that's the reason you get segfault.

The reason your initialization is incorrect is that you are initializing struct members, not the struct itself. Also you are doing this in a wrong way.

There are 2 ways for initializing a struct :

  1. Using stack allocated struct:

    struct example {
      int foo;
    };
    int main() {
      struct example e;
      e.foo=1;
    }
    
  2. Using heap allocated struct with help of malloc():

    struct example {
      int foo;
    };
    int main() {
      struct example *e=malloc(sizeof(struct example));
      e->foo=1;
    }
    

Please note that when you are assigning value to a member of a struct from its pointer (heap allocated struct) you have to use '->' but for the normal struct (the stack allocated one) you have to use '.' .

like image 54
alireza_fn Avatar answered Oct 07 '22 07:10

alireza_fn


Your assumption is correct: a pointer hasn't memory for the object it is supposed to point on its own, you need to allocate it yourself.

Anyway, as juanchopanza noted: you don't need a pointer and a memory allocation if you're dealing with a local object.

Both techniques follow:

typedef struct Node {
    void* data;
    int ref;
    struct Node* next;
} Node;
typedef struct Node* NodePtr;

int main() {

        NodePtr node = (NodePtr)malloc(sizeof(Node));
        node->data = 0;
        node->next = 0;
        node->ref = 42;
        printf("%d", node->ref);

        Node obj = {0,42,0}; // this is not on the heap
        printf("%d", obj.ref);

The other syntaxes you tried are not correct. Not even part of the language.

like image 26
Marco A. Avatar answered Oct 07 '22 05:10

Marco A.