Question

I'm reading the Gforth manual on memory allocation / deallocation, and this is something I cannot understand. Suppose I allocated a chunk of memory to hold four integers like this:

create foo 1 , 2 , 3 , 4 ,

Then, maybe I allocated more memory and perhaps deallocated some too, and now I want to deallocate foo. How do I do that? Doing foo free and foo 4 cells free results in an error.

Was it helpful?

Solution

One option is to use forget foo but that will 'deallocate' everything that you have defined since you defined foo, and worse than that Gforth doesn't implement it. In Gforth you have to use a 'marker', but this also will revert everything that happened after the marker.

For example (I'll show what you would get entering this into a Gforth interpreter, including the interpreter's responses (denoted by double asterisks)):

marker -unfoo **ok**

create foo 1 , 2 , 3 , 4 , **ok**

/ A test word to get the first thing in foo (1) back
: test foo @ . ; **ok**

test **1 ok** 

-unfoo **ok**

foo

**:8: Undefined word
>>>foo<<<
Backtrace:
$7FAA4EB4 throw
$7FAB1628 no.extensions
$7FAA502C interpreter-notfound1**

test

**:8: Undefined word
>>>test<<<
Backtrace:
$7FAA4EB4 throw
$7FAB1628 no.extensions
$7FAA502C interpreter-notfound1**

The example is meant to illustrate that foo and test are both gone after you execute -unfoo.

How this actually works is probably my moving the address that the interpreter is taking as the last thing added to the dictionary. -unfoo moves this back to before the address at which foo was added, which is equivalent to freeing the memory used by foo.

Here is another reference for this Starting Forth which is pretty excellent for picking up Forth in general.


In response to a comment on this answer:

This question is quite similar and this answer is pretty helpful. This is probably the most relevant part of the Gforth documentation.

The links above explain Forth versions of malloc(), free() and resize().

So in answer to your original question, you can use free but the memory that you free has to have been allocated by allocate or resize.

create adds an item to the dictionary and is as such not exactly what you want if you are going to want the memory back. My understanding of this, which may be incorrect is that you wouldn't normally remove things from the dictionary during the course of normal execution.

The best way to store a string depends on what you want to do with it. If you don't need it to exist for the lifetime of the programme you can just use s" by itself as this returns a length and an address.

In general, I would say that using create is quite a good idea but it does have limitations. If the string changes you will have to create a new dictionary entry for it. If you can set an upper bound on the string length, then once you have created a word you can go back and overwrite the memory that has been alloted for it.

This is another answer that I gave that gives an example of defining a string word.

So in summary, if you really do need to be able to deallocate the memory, use heap methods that Gforth provides (I think that they are in the Forth standard but I don't know if all Forths implement them). If you don't you can use the dictionary as per your question.

OTHER TIPS

The CREATE ALLOT and VARIABLE words consume dictionary space (look it up in the ISO 93 standard.) Traditionally you can

FORGET aap

, but that removes aap and each definition that is defined later than aap , totally different from free().

In complicated Forth's like gforth this simple mechanism no longer works. It amounted to truncating the linked list and resetting an allocation pointer (HERE/DP)

In gforth you are obliged to use MARKER. In putting

MARKER aap

you can use aap to remove aap and later defined words. MARKER is cumbersome and it is much easier to restart your Forth.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top