Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Behavior of realloc when the new size is the same as the old one

Tags:

c

memory

realloc

I'm trying to make a code more efficient. I have something like this:

    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++;
    }

The memory is being allocated dynamically. I would like to reduce the realloc calls to make the code more efficient. I would like to know how realloc would behave if the new size is equal to the old one. Will the call be simply ignored?

like image 299
H_squared Avatar asked Sep 04 '13 15:09

H_squared


People also ask

Can you realloc to a smaller size?

Yes, guaranteed by the C Standard if the new object can be allocated. (C99, 7.20. 3.4p2) "The realloc function deallocates the old object pointed to by ptr and returns a pointer to a new object that has the size specified by size."

Can realloc return the same pointer?

realloc() returns a pointer to the newly allocated memory, which is suitably aligned for any kind of variable and may be different from ptr, or NULL if the request fails.

Does realloc clear old memory?

No, the data will be copied for you into the new block that the returned p points at, before the old block is freed. This all happens before realloc returns, so the new p points to your data still.

Can realloc to smaller size fail?

Yes, it can. For example, if a particular implementation uses different pools for different object sizes, realloc() may actually allocate a new block in the pool for smaller objects and free the block in the pool for larger objects. Thus, if the pool for smaller objects is full, it will fail and return NULL .


3 Answers

It's not specified in standard C. All standard C guaranteed is: the contents of the new object shall be the same as that of the old object prior to deallocation, up to the lesser of the new and old sizes.

However, if you are using GNU libc, it says explicitely to return the same address, see here for detail.

If the new size you specify is the same as the old size, realloc is guaranteed to change nothing and return the same address that you gave.

like image 63
Yu Hao Avatar answered Oct 20 '22 17:10

Yu Hao


I wouldn't count on realloc behaving as a no-op if the size doesn't change (although it seems a reasonable thing for it to do), but then you don't have to: if the value of iCount hasn't changed, don't make the call to realloc.

like image 38
Scott Hunter Avatar answered Oct 20 '22 17:10

Scott Hunter


The C standard doesn't specify what will happen, so you're at the mercy of the implementation. I can't imagine any half-decent implementation that will not return the pointer passed in, but the safe option is to check whether the size of the allocation has changed in your own code. That will also certainly skip a function call.

(BTW, please don't cast the return value from realloc. It's not necessary and it may hide undefined behavior if you forget to #include <stdlib.h>.)

like image 28
Fred Foo Avatar answered Oct 20 '22 16:10

Fred Foo