| Summary: | Realloc() doesn't (by default) comply with the ANSI C standard, and realloc(ptr, 0) with malloc_sysv set will cause an out of memory error if malloc_xmalloc is also set. | ||
|---|---|---|---|
| Product: | Base System | Reporter: | Farooq Mela <fmela0> |
| Component: | misc | Assignee: | Poul-Henning Kamp <phk> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | ||
| Priority: | Normal | ||
| Version: | 4.3-STABLE | ||
| Hardware: | Any | ||
| OS: | Any | ||
Responsible Changed From-To: freebsd-bugs->phk Malloc is phk's baby. State Changed From-To: open->closed I've fixed the realloc(foo,0) problem with option VX The other issue (return value of malloc(0)) breaks too much software to be changed currently. |
The ANSI C standard requires that realloc(ptr, 0) behave the same as free(ptr). This behaviour is available on FreeBSD only if the malloc_options includes 'V' (sysv-style). Secondly, if both 'V' and 'X' are in malloc_options, specifying SysV-style and abort-on-out-of-memory behaviour, then realloc(ptr, 0) will result in realloc free'ing the pointer, and then thinking it is out of memory and abort()ing. Fix: Change line 1132 of /usr/src/lib/libc/stdlib/malloc.c: - if (malloc_xmalloc && !r) + if (malloc_xmalloc && !r && size) Change line 1121: - if (malloc_sysv && !size) + if (ptr && !size) This will cause the implementation to conform with ANSI as well as fix the problem where it thinks it is out of memory when it is really just freeing the pointer. How-To-Repeat: #inlude <stdlib.h> int main(void) { extern char *malloc_options; void *p=NULL; malloc_options="VX"; /* set malloc flags */ p=realloc(p, 50); /* allocate 50 bytes */ p=realloc(p, 0); /* this will cause realloc to abort() */ exit(0); }