开发者

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

开发者 https://www.devze.com 2023-04-05 19:25 出处:网络
I have the following code: #include <stdio.h> #include <stdlib.h> #define OUT void getDataFromServer(OUT int** array, OUT int* size)

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 pointe开发者_JS百科r 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!


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);


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.


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消