4

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

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

4

2 回答 2

2

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

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

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

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

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

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

于 2011-02-07T20:28:50.170 回答
1

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

于 2009-09-04T05:01:26.900 回答