A variable declared inside a function is local. The scope of a local variable is limited to the function range inside which it is declared. Local variable can be initialized by outcome of any expression. Every call of the function initializes a local variable. Local variables are stored in memory area of the corresponding function.
Scope of a variable is a program part, in which a variable can be referred to. Variables declared inside a block (at the internal level), have the block as their scope. The block scope start with the variable declaration and ends with the final right brace.
Local variables declared in the beginning of a function also have the scope of block, as well as function parameters that are local variables. Any block can contain variable declarations. If blocks are nested and the identifier in the external block has the same name as the identifier in the internal block, the external block identifier is hidden, until the operation of the internal block is over.
This means that while the internal block is running, it sees values of its own local identifiers, not the values of identifiers with identical names in the external block.
Local variables declared as static have the scope of the block, despite the fact that they exist since the program start.
In every MQL5 program, a special memory area called stack is allocated for storing local function variables that are created automatically. One stack is allocated for all functions, its default size for indicators is equal to 1Mb. In Expert Advisors and scripts, stack size can be managed using the #property stacksize compiler directive (which sets the stack size in bytes), a memory of 8Mb is allocated by default for the stack.
Static local variables are stored in the same place where other static and global variables are stored - in a special memory area, which exists separately from the stack. Dynamically created variables also use a memory area separate from the stack.
With each function call, a place on the stack is allocated for internal non-static variables. After exiting the function, the memory is available for use again.
If from the first function the second one is called, then the second function occupies the required size from the remaining stack memory for its variables. Thus, when using included functions, stack memory will be sequentially occupied for each function. This may lead to a shortage of memory during one of the function calls, such a situation is called stack overflow.
Therefore, for large local data you should better use dynamic memory - when entering a function, allocate the memory, which is required for local needs, in the system (new, ArrayResize()), and when exiting the function, release the memory (delete, ArrayFree()).