Forth DISCUSSION

Forth VARIABLE, CREATE and ALLOT: how do I reserve a buffer or an array, and can I free it?

Started by silent96 Forth CREATE ALLOTdictionary memoryCELLSarray defining wordsALLOCATE and FREE
5 replies 248 views 6 participants
Latest activity · 30 Sep 2026

Forth VARIABLE, CREATE and ALLOT: how do I reserve a buffer or an array, and can I free it?

silent96 Forth Forum
#1

I need a 16-element sample buffer and a lookup table in a Forth program for a microcontroller board. I know VARIABLE gives one cell, and I have seen CREATE BUF 16 CELLS ALLOT and CREATE TABLE 10 , 20 , 30 , in examples without really understanding what is happening. My first attempt, BUF 3 + @, returns garbage for the fourth element.

How does Forth allocate memory for data, how do I index into it correctly, and is there any way to release it again?

Community replies 5

Re: Forth VARIABLE, CREATE and ALLOT: how do I reserve a buffer or an array, and can I free it?

#2

Data normally lives in the dictionary, the same growing region that holds your definitions. HERE returns the address of its first free location. CREATE BUF makes a new word that, when executed, pushes the address HERE had at that moment. ALLOT then advances the free pointer by the given number of address units, reserving the space behind the name: 16 CELLS ALLOT reserves 16 cells.

, (comma) stores one cell at HERE and advances by one cell, so CREATE TABLE 10 , 20 , 30 , builds an initialised three-entry table. VARIABLE X is essentially CREATE X 1 CELLS ALLOT.

Re: Forth VARIABLE, CREATE and ALLOT: how do I reserve a buffer or an array, and can I free it?

#3

Your indexing bug is the missing CELLS. Addresses count in bytes on almost every system, and a cell is 2, 4 or 8 bytes depending on whether the Forth is 16, 32 or 64 bit. Element i is at the base address plus i CELLS: the fourth element is BUF 3 CELLS + @. On a 32-bit system that is an offset of 12 bytes, whereas BUF 3 + points into the middle of the first cell. TABLE 2 CELLS + @ returns 30.

For byte data use C@, C! and CHARS, and reserve with CREATE LINE 80 CHARS ALLOT.

Re: Forth VARIABLE, CREATE and ALLOT: how do I reserve a buffer or an array, and can I free it?

#4

To avoid repeating the address arithmetic, define an array-defining word with CREATE ... DOES>: : ARRAY ( n -- ) CREATE CELLS ALLOT DOES> ( i -- addr ) SWAP CELLS + ;. Then 16 ARRAY SAMPLES creates the buffer, 42 3 SAMPLES ! stores 42 in element 3 and 3 SAMPLES @ reads it back. The part before DOES> runs when an array is defined; the part after runs each time the array's name is used, with the data address already on the stack.

There is no bounds checking. An index of 16 writes into whatever was defined next. Add a check inside the DOES> part while debugging if you want one.

Re: Forth VARIABLE, CREATE and ALLOT: how do I reserve a buffer or an array, and can I free it?

#5

Two things to know about the space you get. ALLOT does not clear it, so initialise explicitly: BUF 16 CELLS ERASE zeroes the buffer. And dictionary space is released only in stack order. MARKER creates a word that, when executed, removes itself and everything defined after it, which is handy for reloading test code but is not a general-purpose free.

Systems that implement the optional memory-allocation word set also offer a heap: 1024 ALLOCATE returns an address and a result code (zero for success), FREE returns the block, and RESIZE changes its size. Small embedded Forths often leave these out, and fixed buffers created at compile time are usually the better design there anyway.

Re: Forth VARIABLE, CREATE and ALLOT: how do I reserve a buffer or an array, and can I free it?

#6

On a microcontroller, check where the system puts things. Forths that compile into flash keep definitions in flash and need variables and buffers in RAM, and they provide their own words for selecting the target memory. A table built with , may end up in flash, which is what you want for constants but means it cannot be changed with ! at run time. These details are system-specific, so read the memory chapter of your Forth's documentation before laying out data.

Also keep alignment in mind after byte-sized allocations: ALIGN rounds HERE up to a cell boundary, which some processors require before the next ,.

TEP COMMUNITY