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...
--
Garth Fletcher