Given:
- NODE *node1 = malloc (sizeof(NODE));
- NODE *node1 = (struct node *) malloc (sizeof(NODE));
- NODE *node1 = (struct node *) malloc (sizeof(NODE *));
- NODE *node1 = malloc (sizeof(NODE *));
ALL ARE BAD
3 and 4 are really bad
3) and 4) are not allocating enough memory for the struct, but only enough memory to hold the pointer to a struct (say 4 bytes on a 32-bit system) and then telling the compiler to treat that memory as if it was enough to occupy a NODE
1) is correct way to allocate enough memory for the structure (caveat other issues described below)
2) is bad practice because what you really mean is:
NODE *node1 = (NODE *) malloc(sizeof(NODE));
even though NODE
is typedef struct node
(2) says that you know that for sure.
Having said that,
All of them are bad practices for a reason explained later on below.
What you really want to do in practice is something like this:
Only use typedefs when you want to keep things really opaque about the inner structure (the way stdio does FILE) it's better practice to use struct foo bar;
in your declaration than typedef
ing the struct. Especially when the structure is exposed to other parts of the program.
typedef
is better used when you want to ensure that a type is uniformly interpreted on different architectures, e.g. the use of typedef unsigned long long uint64_t
vs typedef unsigned uint64_t
on 32-bit and 64-bit intel x86 cpus in stdint.h
A good example
struct node {
struct node *next;
size_t n_dlen;
void * n_data;
};
int main() {
struct node *node;
node = malloc(sizeof(*node));
}
Notice that I used sizeof(*node) instead of sizeof(struct node), because if I decide later on that node should be some other type say struct new_node *
then all i have to do is change the declaration and the sizeof(*node)
will still be okay.