When you write
person * myperson = malloc(sizeof(person));
it allocates memory for the myperson
variable (pointer), i.e, for the myperson->name
and myperson->age
member variable themselves.
The memory location, pointed by myperson->name
(being a pointer), is not valid, till time. In other words, myperson->name
itself is a valid access, but the moment you try to use the content of the memory location pointed by myperson->name
, it'll be UB as the pointer value is indeternminate. You need to allocate memory separately to the pointer.
Following that,
myperson->name = "John";
is valid, as you're storing the starting address of the string literal "John"
to the pointer. After this you can use the pointer content. (Remember, as myperson->name
point to a string literal, you may not change it.)
To extend this answer, let me state, if you want to copy a string into the memory location pointed by myperson->name
, then, first, you need to allocate memory to myperson->name
first. For example,
myperson->name = malloc(32); //allocate memory
strcpy(myperson->name, "Hello"); //write to that memory