【问题标题】:Using realloc in clang to shrink memory在 clang 中使用 realloc 来收缩内存
【发布时间】:2011-11-20 18:59:30
【问题描述】:

我在涉及 realloc 的 clang 代码中遇到了问题。这段代码在 gcc 和 Visual Studio 下运行良好,所以我有兴趣了解 clang 的行为。我们的代码执行与此类似的操作(省略了错误处理等):

// allocate way more memory than we need
char * memory = malloc(500000);
int memoryused = 0;

// ... code goes here that fills up the memory, keeping track by
// setting memoryused ...

// now we're done, shrink the memory down to the size it needs
memory = realloc(memory, memoryused);

在 gcc 和多个版本的 MSVC 下,内存指针没有移动。但是,在clang下,它似乎移动了内存,即使所需的大小只有1-2000字节。

clang 这样做有什么特别的原因吗?我能想到的唯一一个可能是它为大小分配或其他东西保留了单独的堆。否则,移动内存似乎有点低效,因为它可以截断旧的内存块并继续使用它而无需复制数据。

【问题讨论】:

  • 顺便说一句,你这样做是个坏主意。您应该始终假设对realloc 的调用都可以返回不同的地址并且失败(返回NULL),即使是减少,因为这是标准所说的。其他任何事情都只是草率的编码(无意冒犯),并且您的收缩操作是潜在的内存泄漏,除非您已将 memory 保存在某处以进行恢复。有关血腥细节,另请参阅stackoverflow.com/questions/3162502/…
  • 是的,我在遇到这个问题后想通了。让我感到奇怪的是,它在除叮当声之外的所有其他东西上都可以正常工作。 :)

标签: c macos osx-lion clang realloc


【解决方案1】:

我曾经也想知道这种事情:Is realloc guaranteed to be in-place when the buffer is shrinking?

总结响应 - realloc 允许移动缓冲区,即使它只是缩小...具体细节取决于您的特定库实现。

来自c99(强调我的):

realloc 函数返回一个指向新对象的指针(可能 具有与指向旧对象的指针相同的值)或空指针 如果无法分配新对象。

正如您所猜测的(以及根据链接问题中的一些回答)一些分配器显然确实对堆进行了分区,因此特定大小范围的分配来自同一个分配桶 -在大量小对象可能散落的情况下防止堆碎片,这将阻止分配大的连续块。

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 2011-04-16
    • 2016-07-04
    • 2017-04-12
    • 2016-08-22
    • 2013-03-09
    • 2020-12-18
    • 2016-04-09
    • 2019-08-04
    • 2015-06-18
    相关资源
    最近更新 更多