Muhammad Hewedy
Muhammad Hewedy

Reputation: 30076

Does realloc just expand the memory or might that lead to memory problems?

I have the following code:

#include <stdio.h>
#include <stdlib.h>
#define OUT

void getDataFromServer(OUT int** array, OUT int* size)
{
    static int tmpArr[] = {0x00, 0x01, 0x02, 0x03,  0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
                        0x10, 0x11, 0x12, 0x13,  0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
    *size = sizeof tmpArr / sizeof(int);
    printf("Before realloc: %p\n", *array);
    *array = realloc(*array, sizeof(*array) * *size);
    printf("After realloc : %p\n", *array);
    int i=0;
    for (; i < *size; i++)
    {
        (*array)[i] = tmpArr[i];
    }
}

int main(void)
{
    int size = 0;
    int* dataFromServer = malloc(sizeof *dataFromServer);
    printf("in main: %p\n", dataFromServer);
    getDataFromServer(&dataFromServer, &size);

    int x;
    for (x=0; x < size; x++)
        printf("%d ", dataFromServer[x]);
    printf("\n\n");
    free(dataFromServer);
    return 0;
}

Output:

in main: 003F1708
Before realloc: 003F1708
After realloc : 003F3430
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31

From the output, the realloc returns a pointer to a new memory address..

So the question is, should I free this location explicitly- besides freeing the location created by original malloc?

Or it is doing what was desired by the code above which is Just expand the memory location reserved previously?

Thanks.

EDIT: Actually, each answer below provided me with a valuable piece of info. And because I've to choose just one Answer to accept. I've chosen the one that corrected my above code!

Upvotes: 2

Views: 1254

Answers (4)

wildplasser
wildplasser

Reputation: 44250

Realloc can do one of three things:

1) it finds out that your previous memory can be expanded without the need tto shufle it around.

2) Is can satisfy your request, but the memory object has to be put in another place.

3) it can fail.

In your case 1) happened, so it seems. EDIT: it did return a different pointer so it chose 2)

BTW in case 3) it returns NULL. Nothing happened and your pointer still points to the valid old object.

Upvotes: 1

Matteo Italia
Matteo Italia

Reputation: 126957

After you called realloc and it returned some pointer you should forget about the previous one and just keep the "new" pointer.

If realloc resized it, then realloc returns it, if it allocated a new space in memory and copied the previous content of it it will free the old pointer and return a new one.

But, never overwrite the old pointer with the result of a call to realloc (as you're doing in your code): in facts, when realloc fails it returns NULL and does not free the old pointer, so, if you are overwriting the only variable where you stored it, you are losing the only way you have to free that memory, and thus you have a memory leak. So, the "canonical" way to call realloc is:

/* assuming myPtr contains the malloced memory */
void * tempPtr=realloc(myPtr, newSize);
if(tempPtr==NULL)
{
    /* realloc failed, handle the error and, if aborting, free myPtr */
}
else
    myPtr = tempPtr;

/* ... */

/* when you no longer need it free the memory */
free(myPtr);

Upvotes: 5

Heisenbug
Heisenbug

Reputation: 39204

should I free this location explicitly- besides freeing the location created by original malloc?

No. realloc should take care of that. Even if the memory is reallocated in a new address space, if realloc succeeds previous allocated memory with malloc is automatically freed.

Upvotes: 2

JaredPar
JaredPar

Reputation: 755577

There are two cases here.

  • Realloc fails: You are only responsible for freeing the original pointer
  • Realloc succeeds: You are only responsible for freeing the returned pointer

Note: The realloc function is not guaranteed to expand a memory location. It can in fact be used to shrink memory by choosing a size of 0.

Upvotes: 4

Related Questions