Освободить память, ранее выделенную для переменной (используя create)
Я читаю руководство Gforth по распределению / освобождению памяти, и это то, что я не могу понять. Предположим, я выделил кусок памяти для хранения четырех целых чисел, как это:
create foo 1 , 2 , 3 , 4 ,
Тогда, может быть, я выделил больше памяти и, возможно, освободил некоторые тоже, и теперь я хочу освободить foo
, Как я могу это сделать? дела foo free
а также foo 4 cells free
приводит к ошибке.
2 ответа
Одним из вариантов является использование forget foo
но это "освободит" все, что вы определили, так как вы определили foo
и хуже того, Gforth не реализует это. В Gforth вы должны использовать "маркер", но это также вернет все, что произошло после маркера.
Например (я покажу, что вы получите, введя это в интерпретатор Gforth, включая ответы переводчика (обозначенные двойными звездочками)):
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**
Пример предназначен для иллюстрации того, что foo
а также test
оба исчезли после того, как вы выполните -unfoo
,
Как это на самом деле работает, возможно, я перемещаю адрес, который переводчик воспринимает как последнее, что добавлено в словарь. -unfoo
перемещает это назад до адреса, по которому foo
был добавлен, что эквивалентно освобождению памяти, используемой foo
,
Вот еще одна ссылка для этого Starting Forth, который довольно хорош для выбора Forth в целом.
В ответ на комментарий к этому ответу:
Этот вопрос очень похож, и этот ответ довольно полезен. Это, вероятно, самая важная часть документации Gforth.
Ссылки выше объясняют Forth версии malloc()
, free()
а также resize()
,
Так что в ответ на ваш оригинальный вопрос, вы можете использовать free
но память, которую вы освобождаете, должна быть выделена allocate
или же resize
,
create
добавляет элемент в словарь и, как таковой, не совсем то, что вы хотите, если вы хотите вернуть память. Мое понимание этого, которое может быть неверным, состоит в том, что вы обычно не удаляете вещи из словаря в ходе обычного выполнения.
Лучший способ сохранить строку зависит от того, что вы хотите с ней сделать. Если вам не нужно, чтобы он существовал на протяжении всей жизни программы, вы можете просто использовать s"
сам по себе, поскольку это возвращает длину и адрес.
В общем, я бы сказал, что с помощью create
это довольно хорошая идея, но у нее есть ограничения. Если строка изменится, вам придется create
новая словарная запись для него. Если вы можете установить верхнюю границу длины строки, то, как только вы create
Да слово, вы можете вернуться и переписать память, которая была allot
для этого.
Это еще один ответ, который я дал, который дает пример определения строкового слова.
Итак, в итоге, если вам действительно нужно иметь возможность освободить память, используйте методы кучи, которые предоставляет Gforth (я думаю, что они соответствуют стандарту Forth, но я не знаю, реализуют ли они все Forths). Если вы не можете использовать словарь в соответствии с вашим вопросом.
Слова CREATE ALLOT и VARIABLE занимают место в словаре (поищите его в стандарте ISO 93). Традиционно вы можете
ЗАБУДЬТЕ
, но это удаляет aap и каждое определение, которое определено позже, чем aap , полностью отличное от free().
В сложных фортах, таких как gforth, этот простой механизм больше не работает. Это сводилось к усечению связанного списка и сбросу указателя выделения (ЗДЕСЬ/DP)
В дальнейшем вы обязаны использовать MARKER. Вкладывая
MARKER aap
вы можете использовать aap для удаления aap и более поздних определенных слов. MARKER громоздок, и перезапустить Форт гораздо проще.