【问题标题】:Deallocate memory previously allocated to a variable (using create)释放先前分配给变量的内存(使用 create)
【发布时间】:2013-08-07 06:57:48
【问题描述】:

我正在阅读有关内存分配/释放的Gforth 手册,这是我无法理解的。假设我分配了一块内存来保存四个这样的整数:

create foo 1 , 2 , 3 , 4 ,

然后,也许我分配了更多内存,也可能释放了一些内存,现在我想释放foo。我怎么做?执行foo freefoo 4 cells free 会导致错误。

【问题讨论】:

  • 大声笑,@PeterMortensen,我敢打赌,有 115 人订阅了forth 标签,没有人找不到 Gforth 手册……用“四”代替 4,来吧。 ..您的编辑绝对不需要,请停止关注我的帖子!这种跟踪狂的行为很奇怪,完全没有必要。
  • @user797257,也许彼得想到了第 116 个人?无论如何,我真的很感谢他的编辑。

标签: memory-management forth gforth


【解决方案1】:

CREATE ALLOT 和 VARIABLE 词占用字典空间(在 ISO 93 标准中查找。) 传统上你可以

忘记 aap

,但是删除了 aap 以及晚于 aap 定义的每个定义,与 free() 完全不同。

在复杂的 Forth 之类的 gforth 中,这种简单的机制不再起作用。它相当于截断链表并重置分配指针(HERE/DP)

在 gforth 中,您必须使用 MARKER。在投入

MARKER aap

您可以使用 aap 来删除 aap 和以后定义的单词。 MARKER 比较麻烦,重启你的 Forth 就容易多了。

【讨论】:

    【解决方案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**
    

    这个例子是为了说明footest在你执行-unfoo之后都消失了。

    这实际上是如何工作的可能是我移动了解释器作为最后添加到字典中的地址。 -unfoo 将其移回到添加foo 的地址之前,相当于释放foo 使用的内存。

    这里是这个Starting Forth 的另一个参考资料,它非常适合学习 Forth。


    回应对此答案的评论:

    This question 非常相似,this answer 非常有用。 This 可能是 Gforth 文档中最相关的部分。

    上面的链接解释了malloc()free()resize()的Forth版本。

    因此,在回答您最初的问题时,您可以使用free,但您释放的内存必须由allocateresize 分配。

    create 将一个项目添加到字典中,因此如果您想要恢复内存,这并不是您想要的。我对此的理解可能不正确,因为在正常执行过程中您通常不会从字典中删除内容。

    存储字符串的最佳方式取决于您想用它做什么。如果您不需要它在程序的生命周期内存在,您可以单独使用s",因为它会返回一个长度和一个地址。

    总的来说,我会说使用create 是个好主意,但它确实有局限性。如果字符串发生变化,您将不得不为它create 一个新的字典条目。如果您可以设置字符串长度的上限,那么一旦您有了created 一个单词,您就可以返回并覆盖已为它使用alloted 的内存。

    This 是我给出的另一个答案,它给出了定义字符串单词的示例。

    总而言之,如果您确实需要能够释放内存,请使用 Gforth 提供的堆方法(我认为它们在 Forth 标准中,但我不知道是否所有 Forth 都实现了它们)。如果你不这样做,你可以根据你的问题使用字典。

    【讨论】:

    • 哦,天哪...这是否意味着我必须编写自己的分配器?也许我只是没有问正确的问题。我想要的只是alloc / free 对。我也有一个印象,这就是 GForth 分配/释放内存的方式。 create 在某种程度上类似于静态分配吗? IE。您通常会在程序中分配/取消分配此类实体,还是这样做不寻常?从技术上讲,我想要的只是有一个地方可以保存可变大小的字符串(在堆上分配的字符串)。
    • @wvxvw 我在答案的末尾添加了一些内容,希望能解决您的评论。
    • 谢谢!我需要稍微详述一下这个例子,但我认为它引导我朝着正确的方向前进。也感谢您的详细解释!
    猜你喜欢
    • 1970-01-01
    • 2012-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-21
    • 2011-03-29
    • 2011-08-23
    • 1970-01-01
    相关资源
    最近更新 更多