【问题标题】:in-place realloc with gcc/linux使用 gcc/linux 就地重新分配
【发布时间】:2010-11-23 03:49:29
【问题描述】:

有这种事吗?我的意思是一些函数,如果可能的话,它会重新分配内存而不移动它,或者如果不可能的话,什么也不做。在 Visual C 中有 _expand 可以满足我的要求。有人知道其他平台的等价物,特别是 gcc/linux 吗?我最感兴趣的是在可能的情况下就地缩小内存(标准 realloc 可能会移动内存,即使它的大小减小,以防有人询问)。

我知道没有标准的方法来做到这一点,我明确要求依赖于实现的肮脏的黑客技巧。列出任何你知道在某处有效的东西。

【问题讨论】:

    标签: memory-management realloc


    【解决方案1】:

    除了使用mmapmunmap 来消除你不需要的多余部分(或mremap,它可以做同样的但不是标准的),没有办法减少一个分配的内存块。而mmap 具有页面粒度(通常为 4k),因此除非您处理非常大的对象,否则使用它会比只留下过大的对象而不缩小它们更糟糕。

    话虽如此,就地收缩内存可能不是一个好主意,因为释放的内存会严重碎片化。一个好的realloc 实现会希望在显着缩小块时移动块,以此作为对内存进行碎片整理的机会。

    我猜你的情况是你有一个分配的内存块,其中有许多其他结构持有指向它的指针,并且你不想使这些指针无效。如果是这种情况,这里有一个可能的通用解决方案:

    1. 将可调整大小的对象分成两个分配,一个固定大小的“头”对象指向第二个可变大小的对象。
    2. 对于其他需要指向可变大小对象的对象,存储一个指向 head 对象指针和一个整数偏移size_tptrdiff_t) 到可变大小对象中。

    现在,即使可变大小对象移动到新地址,对它的任何引用都不会失效。

    如果你从多个线程中使用这些对象,你应该在头对象中放置一个读写锁,当你需要访问可变大小的对象时对其进行读锁定,并在调整对象大小时对其进行写锁定可变大小的对象。

    【讨论】:

      【解决方案2】:

      another forum 上提出了类似的问题。我看到的更合理的答案之一是使用mmap 进行初始分配(使用MAP_ANONYMOUS 标志)并调用mremap 没有 MREMAP_MAYMOVE 标志。但是,这种方法的一个限制是分配大小必须是系统页面大小的精确倍数。

      【讨论】:

        猜你喜欢
        • 2014-10-25
        • 2018-01-16
        • 1970-01-01
        • 1970-01-01
        • 2019-10-14
        • 2020-03-17
        • 2017-08-25
        • 2018-05-18
        • 1970-01-01
        相关资源
        最近更新 更多