In C, can non-local function and procedure variables be found in the heap and static zone? in the heap those allocated dynamically, i.e. using malloc and calloc. In the static area, however, there are global variables accessible from all points of the program, right? in the stack instead there are the local variables of the functions or procedures right?
Where objects are stored by C implementations is complicated; it is not solely determined by whether a variable is “local” or not. Two variables defined inside a function, with the same scope for their names, may be stored in different places because one is declared with static
and the other is not.
The C standard does not define any variables as “local” or “global.” It does not even use these words to describe variables except one passing instance related to the names of the parameters of main
. And the standard does not use the word “procedure” at all.
In C, a variable is composed of two parts: An identifier (name) and memory that is used for the variable. The memory is called an object.
Regardless of where a variable is declared or how an object is created, an object is accessible throughout a program, for the duration of the object’s lifetime. In the C standard, “access” means to read or write an object, and any part of a program can read or write an object if it has the object’s address (except that writing to an object defined with const
is not defined).
If you are concerned about “local” and “global” variables, you are likely actually concerned with the scope of the identifier. The scope is the region of program source code where the identifier can be used to refer to its associated object (except when it is hidden by another declaration of the same identifier in an inner scope).
In ordinary general-purpose C implementations, where an object is stored is determined by its storage duration. C has four storage durations:
Automatic storage duration: A function parameter or an object declared inside a function without static
has automatic storage duration. These objects are stored on the stack or, due to optimization, held in registers or optimized away (and sometimes a mix of these, including being in different registers or places on the stack at different times).
Thread storage duration: An object declared with _Thread_local
has thread storage duration. I have not had occasion to be concerned with where they are stored, but I presume it is in memory allocated when the thread is created.
Static storage duration: An object declared without _Thread_local
and either outside a function or inside a function with static
has static storage duration. You might think of these as being stored in what you are calling the “static zone.” However, there may be multiple program sections for them. Notably, static objects that are to be initialized to zero may be stored in a program section specifically for that purpose, while static objects with non-zero initial values may be stored in another program section. The zero-filled section is initialized by the operating system when memory for it is provided, so it occupies little space in the program executable. The not-zero-filled section is initialized by reading data from the program executable file into memory.
Allocated storage duration: An object created by calls to the memory management functions, such as malloc
and free
, has allocated storage duration. The memory used for this is called the heap, although that is something of a misnomer we are stuck with for historical reasons.
The above is a common scheme used for C implementations, but the C standard permits other implementations.
Note that “local” may be an apt description of identifiers with block scope, but “global” is not entirely correct for any identifiers in C other than keywords. C has identifiers with file scope (the name is known throughout its translation unit from the point of declaration on) and external linkage (different declarations of the name in different translation units can be linked to the same entity) but does not have any global identifiers. For an identifier to be truly global, declaring it once in the program would have to make it known throughout the program. C does not have that; to use an identifier in multiple translation units, it has to be declared separately in each unit.