Dynamically allocated memory is any memory that is not statically allocated.
To allocate memory dynamically you can use the
String functions, all flavours of
New, and the versatile
But because the memory is dynamically allocated it must be explicitly deallocated when no longer needed.
In all the above cases, though, any memory that is still allocated when the program terminates will be deallocated automatically.
Another way to allocate memory dynamically is to use the Amiga system functions based on
However, these functions require that the memory allocated using them be deallocated (using functions like
FreeMem) before the program terminates, or else it will never be deallocated (not until your machine is rebooted, anyway).
It is safer, therefore, to try to use the E functions for dynamic allocation whenever possible.
There are many reasons why you might want to use dynamic allocation, and most of them involve initialisation of pointers.
For example, the declarations in the section about static allocation can be extended to give initialisations for the pointers declared in the second
DEF line (see 14.1 Static Allocation).
DEF a:ARRAY, m:myobj, s:STRING DEF a:PTR TO CHAR, m:PTR TO myobj, s:PTR TO CHAR a:=New(20) m:=New(SIZEOF myobj) s:=String(20)
These are initialisations to dynamically allocated memory, whereas the first line of declarations initialise similar pointers to statically allocated memory. If these sections of code were part of a procedure then, since they would now be local variables, there would be one other, significant difference: the dynamically allocated memory would not automatically be deallocated when the procedure returns, whereas the statically allocated memory would. This means that we can solve the deallocation problem (see 14.2 Deallocation of Memory).
/* This is the correct way of doing it */ PROC fullname(first, last) DEF full full:=String(40) StrCopy(full, first) StrAdd(full, ' ') StrAdd(full, last) ENDPROC full PROC main() DEF f, g WriteF('Name is \s\n', fullname('Fred', 'Flintstone')) f:=fullname('Fred', 'Flintstone') g:=fullname('Barney', 'Rubble') WriteF('Name is \s\n', f) ENDPROC
The memory for the E-string pointed to by
full is now allocated dynamically, using
String, and is not deallocated until the end of the program.
This means that it is quite valid to pass the value of
full as the result of the procedure
fullname, and it is quite valid to dereference the result by printing it using
However, this has caused one last problem: the memory is not deallocated until the end of the program, so is potentially wasted since it could be used, for example, to hold the results of subsequent calls.
Of course, the memory can be deallocated only when the data it stores is no longer required.
The following replacement
main procedure shows when you might want to deallocate the E-string (using
PROC main() DEF f, g f:=fullname('Fred', 'Flintstone') WriteF('Name is \s, f points to $\h\n', f, f) /* Try this with and without the next DisposeLink line */ DisposeLink(f) g:=fullname('Barney', 'Rubble') WriteF('Name is \s, g points to $\h\n', g, g) DisposeLink(g) ENDPROC
If you run this with the
DisposeLink(f) line you'll probably find that
g will be a pointer to the same memory as
This is because the call to
DisposeLink has deallocated the memory pointed to by
f, so it can be reused to store the E-string pointed to by
If you comment out (or delete) the
DisposeLink line, then you will find that
g always point to different memory.
In some ways it is best to never do any deallocation, because of the problems you can get into if you deallocate memory too early (i.e., before you've finished with the data it contains).
Of course, it is safe (but temporarily wasteful) to do this with the E dynamic allocation functions, but it is very wasteful (and wrong) to do this with the Amiga system functions like
Another benefit of using dynamic allocation is that the size of the arrays, E-lists and E-strings that can be created can be the result of any expression, so is not restricted to constant values.
(Remember that the size given on
STRING declarations must be a constant.)
This means that the
fullname procedure can be made more efficient and allocate only the amount of memory it needs for the E-string it creates.
PROC fullname(first, last) DEF full /* The extra +1 is for the added space */ full:=String(StrLen(first)+StrLen(last)+1) StrCopy(full, first) StrAdd(full, ' ') StrAdd(full, last) ENDPROC full
However, it may be very complicated or inefficient to calculate the correct size. In these cases, a quick, constant estimate might be better, overall.
The various functions for allocating memory dynamically have corresponding functions for deallocating that memory. The following table shows some of the more common pairings.
Allocation Deallocation ------------------------------ New Dispose NewR Dispose List DisposeLink String DisposeLink NEW END FastNew FastDispose AllocMem FreeMem AllocVec FreeVec AllocDosObject FreeDosObject
END are versatile and powerful operators, discussed in the following section.
The functions beginning with
Alloc- are Amiga system functions and are paired with similarly suffixed functions with a
See the Rom Kernel Reference Manual for more details.
Go to the Next or Previous section, the Detailed Contents, or the Amiga E Encyclopedia.