代码之家  ›  专栏  ›  技术社区  ›  Gary Willoughby

实现动态堆栈类型的最佳方法?或者我滥用realloc?

  •  1
  • Gary Willoughby  · 技术社区  · 15 年前

    我使用的是一种晦涩的语言,它没有本机堆栈类型,所以我实现了自己的堆栈类型。现在,在网上阅读,我发现了一些不同的方法来做到这一点。

    这是我的实现(psuedo代码)

    //push method
    function Push(int)
    {
        Increase (realloc) stack by 4 bytes;
        Push int into the new memory area;
    }
    
    //pop method
    function Pop()
    {
        collect int from the top of the stack;
        reallocate (realloc) the stack to shrink it by 4 bytes;
        return int;
    }
    

    现在有人说,在弹出一个值后使用realloc()调用调整堆栈的大小对性能不利,所以我有几个问题:

    1. 是否最好使用malloc增加堆栈,然后在程序结束时释放它?
    2. 要调整堆栈大小(推送),最好增加4个字节或更多?
    3. 当栈被填满时,通过加倍分配的内存来增加栈的容量是最佳实践吗?
    4. 你对上述代码有什么看法?
    3 回复  |  直到 15 年前
        1
  •  3
  •   EFraim    15 年前

    标准的技术是仅将大小增加2倍,并且仅在有效内存使用少于四分之一时将其缩小。

    这样,您就可以确保使用的内存永远不会超过O(您需要的内存),并且还可以证明堆栈是按固定时间摊销的。

    (用这种方式看:你为每一个进入或退出堆栈的项目支付三美分。其中两个将在下次复制时使用。)

    Link to wikipedia article explaining in more details

        2
  •  0
  •   Ned Batchelder    15 年前

    绝对不要一次增长和收缩4个字节。您的堆将变得非常零碎,您将在分配器中花费太多时间。即使在内存有限的体系结构中,您也不希望像这样对内存进行微管理。

    选择“页面大小”,并按该值递增。建议将尺寸加倍是很常见的,但我不知道为什么会这样。您可能更了解如何使用堆栈来了解如何最好地增加大小。

        3
  •  0
  •   Javier    15 年前

    在流行的库中实现的几乎每一个可变大小的结构都会做一些小的优化,以避免总是重新分配。记住,它通常必须复制数据以使其更大。

    通常它的生长量更大。一个常见的策略是将规模扩大一倍,直到达到某个限制,然后在那里以固定的数量增长。对于收缩,不要担心调整大小,直到它浪费一半以上的大小。

    但是,一些realloc()实现已经在幕后为您实现了这一点。唉,我怀疑你的“晦涩语言”是不是……