i am using void *realloc(void *pointer, size_t size); to increase the size of my pointer. how does realloc work?
does it create a nre address space, and copy the old value to the new address space and returns a pointer this address? or it just allocates more memory and binds it to the old one?
-
3You can easily find answer in man pages.Kylo– Kylo2011-03-16 07:52:33 +00:00Commented Mar 16, 2011 at 7:52
-
possible duplicate of Understanding ReallocJens Gustedt– Jens Gustedt2011-03-16 09:46:07 +00:00Commented Mar 16, 2011 at 9:46
5 Answers
@Iraklis has the right answer: it does the second (if it can get away with it) or the first (but only if it has to).
However, sometimes it can do neither, and will fail. Be careful: If it can't resize your data, it will return NULL, but the memory will NOT be freed. Code like this is wrong:
ptr = realloc(ptr, size);
If realloc returns NULL, the old ptr will never get freed because you've overwritten it with NULL. To do this properly you must do:
void *tmp = realloc(ptr, size);
if(tmp) ptr = tmp;
else /* handle error, often with: */ free(ptr);
On BSD systems, the above is turned into a library function called reallocf, which can be implemented as follows:
void *reallocf(void *p, size_t s)
{
void *tmp = realloc(p, s);
if(tmp) return tmp;
free(p);
return NULL;
}
Allowing you to safely use:
ptr = reallocf(ptr, size);
Note that if realloc has to allocate new space and copy the old data, it will free the old data. Only if it can't resize does it leave your data intact, in the event that a resize failure is a recoverable error.
4 Comments
ptr = realloc(ptr, size); is not wrong if followed by if( !ptr ) fatal_error(); ... and it's rare to do anything else. Of course, if you do try to recover from OOM by freeing existing data (e.g., weak pointers), then the ptr = usage is quite bad. The moral is that you should never call plain malloc or realloc, only wrapped versions that possibly attempt to recover memory and die or throw an exception (longjmp in C) if the memory can't be allocated. Of course, if programming in C++, one should use new or, better yet, the STL.reallocf. Particularly, p could be NULL. if tmp == NULL, you'd free a NULL pointer.free(NULL) does nothing, it's perfectly safe to do.You're misusing the term "address space". All of the memory of your process exists within a single address space. The memory not used by your program, its global variables, and its stack are known as the "heap". malloc and realloc (and calloc, which is just malloc and clear) allocate memory from the heap. Most implementations of realloc will check if there is enough (size bytes) free space starting at pointer (which must point to a block previously allocated by malloc or realloc -- realloc knows how large that block is) and, if so, just increase the size of the block allocated at the location given by pointer and return, with no copying. If there isn't enough space, it will do the equivalent of newptr = malloc(size); memcpy(newptr, pointer, size_of_old_block); free(pointer); return newptr; ... that is, it will allocate a block big enough to hold size bytes, copy the data at pointer to that block, free the old block, and return the address of the new block.
Comments
I think the answer is function is dependent on the requested size and available heap.
From the programmers perspective, I think all we get guaranteed is that pointer is non-null if the new allocation is successful. The pointer may, therefore, remain unchanged even though it now points to a larger block of memory represented by size_t.
Comments
Realloc does not change the size of your pointer, the size of pointers is always the same on the same architecture. It changes the size of the allocated memory to which your pointer points. The way it works is described here: http://msdn.microsoft.com/en-us/library/xbebcx7d.aspx. In short, yes, it allocates more memory leaving your content unchanged; if the memory must be moved, it copies the content. OF course, you can specify a shorter size, in which case it trims the allocated memory, again leaving the content untouched.