Variables stored on the stack are temporary. They belong to the function, etc., And when the function returns and the corresponding stack stack crashes, the stack variables disappear with it. Since global objects are intended to be accessed everywhere, they should not go out of context and, therefore, are stored on the heap (or in a special section of the binary file data), and not on the stack. The same goes for static variables; since they must hold their value between function calls, they cannot disappear when the function returns, therefore they cannot be allocated on the stack.
Regarding the protection of static variables, IIRC is mostly done by the compiler. Although the variable is on the heap, your compiler knows the limited context in which the variable is valid, and any attempt to access static from outside this context will result in an "unknown identifier" or similar error. The only other way to access the heap variable is incorrect if you know the static address and you blindly delete the link to the pointer to it. This should result in a memory access error at runtime.
In a multi-threaded environment, you can still use global variables and static variables. However, you must be much more careful. You must ensure that only one thread can access the variable at a time (usually through some kind of locking mechanism such as a mutex). In the case of local static variables inside a function, you need to make sure that your function will still function properly if it is called from multiple threads sequentially (i.e. it is called from thread 1 and then from thread 2, then thread 1, then thread 2 etc. etc.). This is usually more complex, and many functions that rely on static member variables are not thread safe because of this ( strtok is a notable example).
source share