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.
精彩评论