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:
Just to clarify the differences a bit.
Thanks for the explanation. I knew about val/var but wasn't so clear about the heap/stack allocation. I didn't know that global varibles go on the heap but did know that calling a procedure caused allocation of locals to the stack.
So I was making a huge allocation on the stack. That's fixed now by using a global. I'm somewhat unclear why the compiler crashed though. I would have thought that if it ran out of stack it would give a warning. But the odd thing is that when the program is being compiled it's not even using the stack yet of course ...
Tom
Thomas D. Schneider, Ph.D. Senior Investigator National Institutes of Health National Cancer Institute Frederick National Laboratory for Cancer Research Gene Regulation and Chromosome Biology Laboratory Molecular Information Theory Group Frederick, Maryland 21702-1201 schneidt@mail.nih.gov http://alum.mit.edu/www/toms
On 18 Feb 2013 at 22:18, Thomas Schneider wrote:
Garth:
Just to clarify the differences a bit.
Thanks for the explanation. I knew about val/var but wasn't so clear about the heap/stack allocation. I didn't know that global varibles go on the heap but did know that calling a procedure caused allocation of locals to the stack.
So I was making a huge allocation on the stack. That's fixed now by using a global. I'm somewhat unclear why the compiler crashed though. I would have thought that if it ran out of stack it would give a warning. But the odd thing is that when the program is being compiled it's not even using the stack yet of course ...
The compiler crash is a different issue from the program crash. There compiler should not crash - in other words, it is a bug. Unfortunately, it is a bug that seems unreproduceable elsewhere, and I am not sure where that leaves us ...
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.greatchief.plus.com/
On 19.2.2013. 10:30, Prof A Olowofoyeku (The African Chief) wrote:
On 18 Feb 2013 at 22:18, Thomas Schneider wrote:
Garth:
Just to clarify the differences a bit.
Thanks for the explanation. I knew about val/var but wasn't so clear about the heap/stack allocation. I didn't know that global varibles go on the heap but did know that calling a procedure caused allocation of locals to the stack.
So I was making a huge allocation on the stack. That's fixed now by using a global. I'm somewhat unclear why the compiler crashed though. I would have thought that if it ran out of stack it would give a warning. But the odd thing is that when the program is being compiled it's not even using the stack yet of course ...
The compiler crash is a different issue from the program crash. There compiler should not crash - in other words, it is a bug. Unfortunately, it is a bug that seems unreproduceable elsewhere, and I am not sure where that leaves us ...
The situation isn't hopeless, as - if having enough time - bug reporter (Prof. Schneider) can scale down to the minimal code that still triggers compiler bug or crash. If I remember well, this is what Frank and I have been doing when bug with SET implementation was triggered only on - then rare and now obsoleted - 64-bit Digital Unix on DEC alpha.
They key is to minimize example code that triggers bug, and then it is possible to generate test case to prevent bug to reappear. Correct implementation of compiler should of course produce correct code on all platforms.
Regards, Mirsad
Mirsad:
The situation isn't hopeless, as - if having enough time - bug reporter (Prof. Schneider) can scale down to the minimal code that still triggers compiler bug or crash. If I remember well, this is what Frank and I have been doing when bug with SET implementation was triggered only on - then rare and now obsoleted - 64-bit Digital Unix on DEC alpha.
They key is to minimize example code that triggers bug, and then it is possible to generate test case to prevent bug to reappear. Correct implementation of compiler should of course produce correct code on all platforms.
My original posting was already trimmed down by 45 fold ... The original program was 14324 bytes and the thing I posted was 2537 bytes INCLUDING some descriptive comments.
However, I have just now trimmed it down further to be 563 bytes, attached.
37% gpc minimalgpccrash.p gpc: Internal error: Illegal instruction: 4 (program gpc1) Please submit a full bug report. See URL:http://www.gnu-pascal.de/todo.html for instructions. 38% uname -a Darwin FR-W-C130981 11.4.2 Darwin Kernel Version 11.4.2: Thu Aug 23 16:25:48 PDT 2012; root:xnu-1699.32.7~1/RELEASE_X86_64 x86_64 39% gpc --version gpc 20070904, based on gcc-3.4.6 Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Tom
Thomas D. Schneider, Ph.D. Senior Investigator National Institutes of Health National Cancer Institute Frederick National Laboratory for Cancer Research Gene Regulation and Chromosome Biology Laboratory Molecular Information Theory Group Frederick, Maryland 21702-1201 schneidt@mail.nih.gov http://alum.mit.edu/www/toms
My original posting was already trimmed down by 45 fold ... The original program was 14324 bytes and the thing I posted was 2537 bytes
Minor correction (I grabbed line length not characters) the original program was 114034 bytes.
Tom
Thomas D. Schneider, Ph.D. Senior Investigator National Institutes of Health National Cancer Institute Frederick National Laboratory for Cancer Research Gene Regulation and Chromosome Biology Laboratory Molecular Information Theory Group Frederick, Maryland 21702-1201 schneidt@mail.nih.gov http://alum.mit.edu/www/toms