Это верно для любых указателей, а не только указателей на структуры.Причина в том, что когда вы объявляете переменную (типа int, char или типа некоторой структуры A), вы указываете компилятору создать новую переменную / экземпляр.Таким образом, компилятор автоматически выделяет память для этой переменной.Но когда вы объявляете указатель на некоторую int или некоторую структуру A, вы, по сути, говорите компилятору, что вам нужна ссылка на некоторую переменную, а не на новую переменную этого типа полностью.Чтобы проиллюстрировать это:
struct A{};
int a,b; // New variable a and b
struct A c,d; // New variables c,d of type struct A
// Now take a look at this:
int *px;
px = &a; // px referencing to a, no new int variable created;
px = &b; // px referencing to b, no new int variable created;
struct A* py;
py = &c; // py referencing to c, no new struct A variable created;
py = &d; // py referencing to d, no new struct A variable created;
Теперь, если вы просто объявите указатель A * p, здесь p ни на что не ссылается.Итак, если вы хотите, чтобы p ссылался на новый экземпляр структуры A, вы должны написать явно:
c
p = (struct A*)malloc(sizeof(struct A));