As already stated in the comments, your question doesn't have anything to do with struct
s. Also, forget about stack and heap for a moment -- C doesn't know these concepts, they are just used by many implementations of C.
What you need to know/learn about is the scope, storage duration and maybe linkage of objects in C:
scope: The scope of an identifier defines the area in which this identifier can be accessed to refer to the object it represents. It is always either the area enclosed by the nearest pair of braces ({ }
) or the entire source file when the identifier is declared outside any braces (called file scope). Example:
int a; // a has file scope
int main(void)
{
int b; // the scope of this variable is the main function
if (1)
{
int c; // this variable can only be referred to inside the if block
c = 1; // valid
}
b = c; // INVALID, c is not "in scope" here
}
storage duration: The storage duration of an object determines how long the object lives. You should know about the following storage durations:
static: An object with static storage duration lives for the entire execution time of the program. A variable declared in file scope has static storage duration by default. You can explicitly give a variable static storage duration using the static
storage class:
int a; // static storage duration by default
int func(void)
{
static int b; // explicit static storage duration.
// If you enter this function multiple times, you will get the SAME variable
}
automatic: An object with automatic storage duration lives exactly as long as execution is inside of its scope (or in a function called from this scope). This is the default for all variables not in file scope. Therefore, the following code is wrong:
int *func(void)
{
int a = 5; // automatic storage duration
return &a; // ERROR
}
once this function exits, a
doesn't exist any more because execution left its scope. So the pointer this function returns doesn't point to a valid object.
There's a storage class specifier for this storage duration, auto
, but since you can't give automatic storage duration to a file scoped variable anyways (it would be meaningless), this keyword is arguably useless. In a function, you could write auto int a;
which is exactly the same as int a;
because it's the default here.
dynamic: An object allocated with malloc()
, calloc()
or realloc()
has dynamic storage duration. This means it lives exactly until you explicitly free()
it. The allocation functions return you a pointer to an object with dynamic storage duration. This is what your example program uses, so returning this pointer from a function is fine. The object will live as long as you like, once you don't need it any more, you have to call free()
.
With this information, you should understand what your code does. I left out thread storage duration and anything about linkage because it doesn't directly relate to your question and you can learn about these things later.
Your struct
just defines a structured data type, this is a type that consists of multiple member objects. It doesn't change anything about the rules above. In your example, your whole struct
, including the array of another struct
, is one allocated object with dynamic storage duration.
Getting back to the first paragraph, a typical C implementation will place objects with static storage duration in a bss segment (allocated on program startup), objects with automatic storage duration on the stack (growing dynamically with each function call) and objects with dynamic storage duration in the heap. But this is just the typical implementation and C would also work on platforms that don't even provide these concepts.