I was experimenting with realloc
, giving it larger and larger sizes and checking whether the same block was reused or not:
int main ( void )
{
char * newstr, * prevstr = NULL;
size_t newsize, prevsize = 0;
printf ("We play with realloc\n");
while (1) {
newsize = prevsize + 1 + prevsize/3; /* add 33% */
newstr = realloc(prevstr, newsize);
if (newstr == NULL) {
printf ("could not alloc newsize=%zu. Sorry\n", newsize);
break;
} else {
printf ("newsize=%zu successfully alloc'ed\n", newsize);
if (newstr == prevstr) {
printf ("newstr = prevstr:\tSame block reused\n");
} else {
printf ("newstr != prevstr:\tNew block alloc'ed\n");
}
prevstr = newstr; prevsize = newsize;
}
}
return (EXIT_SUCCESS);
}
As expected, one eventually reaches a point where the size is too large and realloc
cannot answer the request. According to the manual, realloc
should return NULL
and set errno = ENOMEM
when it does not succeed.
This is not what happens when I run the above code on my machine, a Mac with "Darwin Kernel Version 15.0.0". Instead of returning NULL, the code crashes and says
malloc: *** mach_vm_map(size=153288611651584) failed (error code=3)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
could not alloc newsize=153288611651277. Sorry
Is this normal? Something I did not understand when reading the man page?
This is not crucial for my code at the moment but I can imagine situations where I'd like to test whether memory can be alloc'ed without risking a crash. Is there a standard way of testing whether alloc will work without risking such crash?
ADDED after mystery is solved (see answers below): there is no crash, just some system error message from malloc that gets in the way of the expected output. See below on how to avoid that.