新大小与旧大小相同时 realloc 的行为

Posted

技术标签:

【中文标题】新大小与旧大小相同时 realloc 的行为【英文标题】:Behavior of realloc when the new size is the same as the old one 【发布时间】:2013-09-08 04:24:30 【问题描述】:

我正在尝试使代码更高效。我有这样的事情:

    typedef struct
    ...
    MAP;



    MAP* pPtr=NULL;
    MAP* pTemp=NULL;
    int iCount=0;
    while (!boolean)
    pTemp=(MAP*)realloc(pPtr,(iCount+1)*sizeof(MAP));
    if (pTemp==NULL)
    ...
    
    pPtr=pTemp;
    ...
    iCount++;
    

内存是动态分配的。我想减少 realloc 调用以使代码更高效。我想知道如果新大小等于旧大小, realloc 会如何表现。调用会被简单地忽略吗?

【问题讨论】:

OT:我觉得(iCount + 1) * sizeof(MAP)至少看起来更好...... @alk:你是对的。会改的。 大多数实现可能会返回相同的指针,但有些实现有时可能会使用具有相同大小的realloc 作为重新定位分配空间的机会,以使将来的分配更容易。 你为什么在乎?无论您是否从 realloc 获得新指针,您的代码都必须工作,因此无论您是否在“必要”时调用 realloc,它都不会对您的代码产生任何影响。无论如何,我怀疑您是否会通过避免 realloc 调用来节省大量执行时间,并且您可能已经浪费了太多时间 :) 提防过早优化(但如果您已经进行了分析或类似情况,请忽略我。) @rici 我的老板希望我能更有效地编程。他建议每次分配比需要更多的内存(如 20*sizeof(MAP)),然后在每次保存 20 个 MAP 时重新分配。这只是一个实验。他自己还没试过,但也想知道。 【参考方案1】:

标准 C 中没有规定。所有标准 C 保证:新对象的内容应与释放前旧对象的内容相同,直至新旧大小中的较小者。

但是,如果您使用的是 GNU libc,它会明确表示要返回相同的地址,详情请参阅 here。

如果您指定的新大小与旧大小相同,realloc 保证不会更改任何内容并返回您提供的相同地址。

【讨论】:

realloc 由 GNU libc 提供,而不是由 gcc 提供,gcc 只是编译器。在许多系统上,gcc 与 GNU libc 以外的库一起使用。【参考方案2】:

如果大小没有改变,我不会指望 realloc 表现为无操作(尽管这样做似乎是合理的),但你不必:如果 iCount 的值没有改变,不要调用 realloc。

【讨论】:

【参考方案3】:

C 标准没有具体说明会发生什么,因此您要听从实现的摆布。我无法想象任何半体面的实现不会返回传入的指针,但安全的选择是检查分配的大小是否在您自己的代码中发生了变化。这也肯定会跳过函数调用。

(顺便说一句,请不要从realloc 转换返回值。这不是必需的,如果您忘记#include <stdlib.h>,它可能会隐藏未定义的行为。)

【讨论】:

我认为检查 realloc 是否返回 NULL 是至关重要的,因为如果它失败,我最终会出现分段错误。据我所知,每个在线可用的 realloc 调用都会检查输出是否为 NULL。 @hhachem: 然后跳过调用,以防分配大小没有改变。

以上是关于新大小与旧大小相同时 realloc 的行为的主要内容,如果未能解决你的问题,请参考以下文章

通过动态分配创建数组后,在C中通过realloc改变内存大小时出现问题

如果新大小更小,可以重新分配指针吗?

realloc 和 memcpy 是如何工作的?

使用 realloc 和 calloc 增加函数内二维数组的大小

我可以假设调用较小大小的 realloc 会释放其余部分吗? [复制]

动态分配内存-realloc