User Tools

Site Tools


allocating_and_freeing_memory_blocks

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

allocating_and_freeing_memory_blocks [2020/06/08 15:46] (current)
richardrussell created
Line 1: Line 1:
 +===== Allocating and freeing memory blocks =====
  
 +//by Richard Russell, June 2020//
 +
 +In BBC BASIC, a block of memory can be allocated either from the heap or from the stack; the statements to do this are as follows:
 +
 +<code bb4w>
 +      DIM memory%% size%
 +</​code>​
 +
 +This statement allocates **size%+1** bytes of contiguous memory from the **heap** and returns a pointer to the first byte in the variable **<​nowiki>​memory%%</​nowiki>​**. ​ Because the heap grows upwards, and only ever increases in size, this block of memory can only be freed by using CLEAR, which destroys all variables, arrays, structures etc. (except the static integer variables A% to Z%).  Therefore this kind of allocation is not suitable for '​dynamic'​ memory.
 +
 +<code bb4w>
 +      DIM memory%% LOCAL size%
 +</​code>​
 +
 +This statement, which can only be used inside a function (FN) or procedure (PROC), allocates **size%+1** bytes of memory from the stack and returns a pointer to the first byte in the variable **<​nowiki>​memory%%</​nowiki>​**. ​  The memory is automatically freed on return from the function or procedure (or on execution of a RESTORE LOCAL statement). ​ As such it is suitable for some dynamic memory applications but only when it's acceptable for the memory to exist only for the duration of a single FN/PROC, and when it's OK to exit and re-enter the FN/PROC in order to resize the block.
 +
 +Although these two options will satisfy most memory allocation requirements,​ sometimes they may be too limiting. ​ If you want to be able to allocate and free memory blocks without the constraints they impose, one option is to call an Operating System API function to do so.  For example in //BBC BASIC for Windows// you can allocate memory using **SYS "​GlobalAlloc"​** and free it again using **SYS "​GlobalFree"​**. ​ Similarly in //BBC BASIC for SDL 2.0// you can allocate memory using **SYS "​SDL_malloc"​** and free it with **SYS "​SDL_free"​**.
 +
 +But, when the amounts of memory you want to allocate are relatively small, there is an alternative approach that does not require API calls and works in both BB4W and BBCSDL. ​ BBC BASIC already has a reasonably sophisticated dynamic memory management mechanism which it uses for **strings**,​ so the trick is to leverage this by allocating the memory block //in a string//​! ​ It turns out that this is relatively straightforward,​ as the function and procedure listed below demonstrate:​
 +
 +<code bb4w>
 +      DEF FN_heapalloc(N%)
 +      LOCAL a$, p%%
 +      a$ = STRING$(N% + 23, CHR$0)
 +      p%% = PTR(a$) + 23 AND -16
 +      SWAP ](p%%-8), ]^a$
 +      = p%%
 +</​code>​
 +
 +This function takes as a parameter the number of bytes of memory that you want to allocate, and returns a pointer to the first byte.  The memory is automatically 16-byte aligned (which is typically the case for the OS-provided allocation functions too) and zero-filled.
 +
 +<code bb4w>
 +      DEF PROC_heapfree(p%%)
 +      LOCAL a$ : SWAP ]^a$, ](p%%-8) : a$ = ""​ : ENDPROC
 +</​code>​
 +
 +This procedure takes as a parameter a pointer to a block of memory allocated with **FN_heapalloc()** and frees it.
 +
 +These routines may not be as efficient or fast as the OS equivalents,​ and they use up space in BASIC'​s heap which the OS allocation functions don't, but nevertheless there may be occasions when they are useful.
allocating_and_freeing_memory_blocks.txt ยท Last modified: 2020/06/08 15:46 by richardrussell