Do we have to malloc a struct?

35,921

Solution 1

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

Solution 2

A pointer isn't a struct. It's a number that tells C where the struct is located in memory. Any varible with type NodePtr is essentially a number.

How does it make sense, then, to set a variable of type NodePtr to a struct? A struct isn't a number!

When you declare it with NodePtr node, it might be set to some undefined value like 0. You can't access that memory, which leads to a segfault. Instead, you locate some memory to use with malloc() and make that variable point there where its fields can be used.


To respond to potrzebie's comment, it seems to work with strings but that's really just syntactic sugar:

#include <stdio.h>

int main() {
  char *a = "Does this make sense?";
  printf("%d\n", a); // %u is the correct one, but this is for illustrational purposes

  return 0;
}


> test.exe
4214884

Solution 3

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.

Share:
35,921
Spag Guy
Author by

Spag Guy

Updated on July 09, 2022

Comments

  • Spag Guy
    Spag Guy almost 2 years

    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?
  • potrzebie
    potrzebie over 9 years
    It should make sense, you can do it with strings.
  • itdoesntwork
    itdoesntwork over 9 years
    @potrzebie char *x = "..."? That's syntactic sugar, it's still a number and the string is stored somewhere else. Was that the reason for downvoting (if it was you)?