当新的大小与旧的大小相同时,realloc的行为是什么?

10

我想使代码更加高效。我有类似于这样的代码:

    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函数会如何表现。它会被简单地忽略吗?


1
OT: 我觉得(iCount + 1) * sizeof(MAP)看起来至少更美观... - alk
@alk:你说得对。我会改正的。 - H_squared
大多数实现可能会返回相同的指针,但有些情况下可能会使用与已分配空间大小相同的realloc来重新定位已分配空间,以便更轻松地进行未来的分配。 - Keith Thompson
你为什么在意呢?无论你从realloc中得到一个新指针还是不得到,你的代码都必须正常工作,因此对于你的代码来说,是否在“不必要”的情况下调用realloc并没有任何区别。无论如何,我怀疑通过避免调用realloc来节省执行时间并不会有太大的帮助,而且你可能已经浪费了太多的时间 :) 警惕过早优化(但如果你进行了分析或类似操作,请忽略我的建议)。 - rici
@rici 我的老板希望我能更高效地编程。他建议每次分配比实际需要多一些的内存(例如20*sizeof(MAP)),然后每当保存了20个MAP时就进行重新分配。这只是一个实验。他自己还没有尝试过,但也想知道结果如何。 - H_squared
3个回答

11

标准C中没有明确规定。所有标准C保证的是:新对象的内容应该与释放前的旧对象相同,只要新旧大小中较小的那个。

然而,如果您使用GNU libc,则它明确指出要返回相同的地址,请参阅此处了解详情。

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


5
realloc由GNU libc提供,而不是编译器gcc提供。在许多系统中,gcc会与除GNU libc之外的其他库一起使用。 - Keith Thompson

3

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


2
C标准没有明确规定会发生什么,所以你要看实现的情况。我无法想象任何一个半靠谱的实现不会返回传入的指针,但是安全起见,在你自己的代码中检查分配的大小是否改变是一个好选择。这样还可以避免函数调用。
(顺便说一下,请不要强制转换realloc的返回值。这是不必要的,如果你忘记了#include <stdlib.h>,它可能会隐藏未定义的行为。)

我认为检查realloc是否返回NULL非常关键,因为如果失败,我最终会遇到分段错误。据我所知,每个可用的在线realloc调用都会检查输出是否为NULL。 - H_squared
@hhachem:如果分配大小不改变,则跳过调用。 - Fred Foo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接