Dynamic Memory Allocation :: realloc(3)
- What if we run out of allocated memory during the run-time of our program and need to give our collection of items more memory?
- Enter
realloc(3), it's prototype:void *realloc(void *ptr, size_t size);
realloctakes in the pointer to the original area of memory to enlarge and how much the total size should be. - So let's give it a try:
ip = realloc(ip, sizeof(ip) + sizeof(int)*5);
Ah... Now we have some more space, by simply giving it the sizeof the complete array and then adding 5 spaces for ints. "I'm a genius!" you say... and then your program segfaults, core dumps and you get laughed at. STOP! This is NOT how you use realloc. Again. The above example is wrong. Why? - First, sizeof(ip) does not give the size of the allocated space originally allocated by malloc (or a previous realloc). Using sizeof() on a pointer only returns the sizeof the pointer, which is probably not what you intended.
- Also, what happens if the realloc on ip fails? ip gets set to NULL, and the previously allocated memory to ip now has no pointer to it. Now we have allocated memory just floating in the heap without a pointer. This is called a memory leak. This can happen from sloppy realloc's and not using
freeon malloc'd space. - So what is the correct way? Take this code for example:
int *tmp;
Now we are creating a temporary pointer to try a realloc. If it fails, then it isn't a big problem as we keep our ip pointer on the original memory space. Also, note that we specified the real size of our original array and now are adding 5 more ints (so 4bytes*(5+5) = 40bytes, on a typical 32-bit machine).
if ((tmp = realloc(ip, sizeof(int) * (INITIAL_ARRAY_SIZE + 5))) == NULL) {
/* Possible free on ip? Depends on what you want */
fprintf(stderr, "ERROR: realloc failed");
}
ip = tmp;