You can reserve memory for a list node in the dictionary with
list% %allot, which leaves the address of the list node on the
stack. For the equivalent allocation on the heap you can use list%
%alloc (or, for an allocate-like stack effect (i.e., with ior),
use list% %allocate). You can also get the the size of a list
node with list% %size and it's alignment with list%
%alignment.

Note that in ANS Forth the body of a created word is
aligned but not necessarily faligned;
therefore, if you do a

create name foo% %allot

then the memory alloted for foo% is
guaranteed to start at the body of name only if
foo% contains only character, cell and double fields.

You can also include a structure foo% as field of
another structure, with:

struct
...
foo% field ...
...
end-struct ...

Instead of starting with an empty structure, you can also extend an
existing structure. E.g., a plain linked list without data, as defined
above, is hardly useful; You can extend it to a linked list of integers,
like this:(5)

list%
cell% field intlist-int
end-struct intlist%

intlist% is a structure with two fields:
list-next and intlist-int.

You can specify an array type containing n elements of
type foo% like this:

foo% n *

You can use this array type in any place where you can use a normal
type, e.g., when defining a field, or with
%allot.

The first field is at the base address of a structure and the word
for this field (e.g., list-next) actually does not change
the address on the stack. You may be tempted to leave it away in the
interest of run-time and space efficiency. This is not necessary,
because the structure package optimizes this case and compiling such
words does not generate any code. So, in the interest of readability
and maintainability you should include the word for the field when
accessing the field.