新大小与旧大小相同时 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 和 calloc 增加函数内二维数组的大小