Reputation: 585
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:
Upvotes: 15
Views: 48186
Reputation: 944
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
:
Using stack allocated struct
:
struct example {
int foo;
};
int main() {
struct example e;
e.foo=1;
}
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 '.
' .
Upvotes: 37
Reputation: 4802
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
Upvotes: 2
Reputation: 43662
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.
Upvotes: 2