-
-
Save sw17ch/7100909 to your computer and use it in GitHub Desktop.
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #define IGNORE(X) ((void)X) | |
| #define MAX_ALLOC (1024 * 1024) | |
| #define MIN_ALLOC (128) | |
| int main(int argc, char * argv[]) { | |
| IGNORE(argc); | |
| IGNORE(argv); | |
| void * ptr = malloc(MIN_ALLOC); | |
| for (int i = 0; i < 100; i++) { | |
| size_t realloc_sz = arc4random_uniform(MAX_ALLOC); | |
| void * new_ptr = realloc(ptr, realloc_sz); | |
| if (NULL == new_ptr) { | |
| printf("Realloc of size: %lu. Realloc failed!\n", realloc_sz); | |
| } else if (new_ptr != ptr) { | |
| printf("Realloc of size: %lu. Pointer changed: (%p -> %p)\n", realloc_sz, ptr, new_ptr); | |
| ptr = new_ptr; | |
| } else { | |
| printf("Realloc of size: %lu. Pointer is the same: (%p)\n", realloc_sz, ptr); | |
| } | |
| } | |
| return 0; | |
| } |
So this makes me wonder again about leaks.
If at the end of the program, after the loop, I free ptr and new_ptr, I'm freeing 0x109137000 (new_ptr) and 0x7fb230803200 (ptr). Aren't the other pointer addresses abandoned but never freed? (I.e. aren't they left unhandled?)
Read the man page closely for realloc, and/or the C standard. The OpenBSD man page is particularly good about documenting realloc's edge cases: http://www.openbsd.org/cgi-bin/man.cgi?query=realloc
Good question. From man realloc:
If there is not enough room to enlarge the memory allocation pointed to by ptr, realloc() creates a new allocation, copies as much of the old data pointed to by ptr as will fit to the new allocation, frees the old allocation, and returns a pointer to the allocated memory.
Happily, realloc takes care of that free for you. The only case where the original pointer passed to realloc should ever be used again is if realloc returns NULL (indicating a failure).
Here's a naive example of what happens inside realloc. Note: this implementation assumes that size is greater-than-or-equal-to the original size of ptr. In other words: this implementation is undefined if size is less than the original allocated size of ptr.
void * realloc(void * ptr, size_t size) {
void * new_ptr = malloc(size);
memcpy(new_ptr, ptr, size);
free(ptr);
return new_ptr;
}Thank you both (again)! At some point, I owe you both a beverage of choice.
Example output on my machine.