As many folks have pointed out you have a problem because in using typedef you went one step too far :-). Using typedef
to recast types is meant for increasing clarity whereas the way you're using it decreases clarity.
Let me first show your example with the correct approach:
#include <stdio.h>
#include <stdlib.h>
struct player {
char letter;
int age;
};
/* typedef struct player *player_t; NOT NEEDED */
int main (void)
{
struct player *p;
p = malloc(sizeof(*p)); /* used *p for sizeof instead of struct player */
if (p == NULL)
{
fprintf(stderr, "Unable to allocate memory\n");
return 1;
}
p->letter = 'A';
p->age = '9';
free(p);
return 0;
}
When to use typedef foo_t bar_t
When it makes things clearer, e.g. stdint.h does this for integers. Say, you want a 32-bit unsigned int, you would use uint32_t which is appropriately typedef'd for various architectures to give you what you expect.
When NOT to use typedef struct foo foo_t
Pretty much all the time.
When it's OK to use typedef struct foo foo_t
Now for the reasons behind the changes, typedef struct foo foo_t
is discouraged except when struct foo is opaque, typically when you are writing a C API where the structure is accessed through predefined access functions that have a longer life than internal structure.
Why use sizeof(*p) instead of sizeof(struct player) ?
In case, for some reason, you decide to change what *p
is then all you have to do is change the declaration, and not worry that it's not going to get appropriately allocated.