Just to clarify the differences a bit.
Space for a global variable is allocated when the program starts, essentially from the "heap" - which is the collection of available memory.
Space for variables allocated by New() or NewPtr() are also allocated from the heap. These allocations can be released by using Dispose.
For example: type myDataType = array... {defines the size of the structure}
in the main program var myData : myDataType; {allocates a global structure in the heap}
however, within a procedure or function procedure myProc; var localdata : myDataType; {allocates a LOCAL structure in the Stack}
The reasoning is simple - the structure is local to that procedure or function, so the intent is to allocate it only as long as the procedure is executing. The Stack was a reasonable way to handle such local structures so that exiting the procedure, unstacks anything that was placed on it when the procedure is called and thus releases that allocated memory. This is OK only as long as the structures are small...
The right way to handle local large structures is to explicitly allocate them upon entry to the procedure and then DEallocate them before exiting the procedure. For example:
type myDataTypePtr : ^myDataType;
procedure myProc; var localdataP : myDataTypePtr; {allocates a POINTER (4 or 8 bytes) on the stack} begin localdataP := NewPtr(sizeOf(myDataType)); {this allocates the structure on the heap, with localdataP} { pointing to that allocated space}
{use the structure via localdataP^ }
dispose(localdataP); {release the allocated memory} end;
There is another gotcha - the difference between passing arguments "by reference" versus "by value". The former uses the VAR prefix to indicate that the procedure will have direct access to the actual data structure. The latter indicates that the called procedure will be given a copy of the original structure, i.e., a LOCAL copy.
procedure myCalledProc (VAR byRef : myDataType; byVal : myDataType);
"VAR byRef" specifies a POINTER to the original data to be passed on the Stack. The compiler takes care of converting any access to byRef within the procedure into a byRef^ and also of creating the pointer.
"byVal" specifies a LOCAL COPY of the data structure to be passed on the Stack, which causes overflow if the copy is too big
In other words, calling
myCalledProc (myData, myData)
creates a pointer to myData and passes that on the stack as byRef it also creates a complete copy of myData and passes that on the Stack as byVal. For big structures the difference is huge...
I hope the above clarifies more than it confuses...