i was debugging a program on FreeBSD 6, and much to my surprise, i noticed that malloc(0) returns 0x800, as shown by this program: > more a.c #include <stdio.h> int main(int argc, char *argv[]) { char *p = malloc(0); printf(" malloc 0 returns %p\n", p); } > cc -o a a.c > ./a malloc 0 returns 0x800 if you look at the source this is indeed clear - internally the 0x800 is ZEROSIZEPTR and is set when a zero length is passed to malloc() unless you have malloc_sysv set. The thing is, i don't know if this behaviour is intentional or not, but certainly is not documented -- the manpage documents something totally different (in the section for the 'V' MALLOC_OPTION, see below). TUNING ... V Attempting to allocate zero bytes will return a NULL pointer instead of a valid pointer. (The default behavior is to make a minimal allocation and return a pointer to it.) This option is provided for System V compatibility. This option is incompatible with the ``X'' option. So what should we do with this ? Just fix the manpage or fix the code ? This behaviour is likely to break quite a few things... cheers luigi
In the last episode (Dec 11), Luigi Rizzo said:> i was debugging a program on FreeBSD 6, and much to my surprise, i > noticed that malloc(0) returns 0x800, as shown by this program: > > > more a.c > #include <stdio.h> > int main(int argc, char *argv[]) > { > char *p = malloc(0); > printf(" malloc 0 returns %p\n", p); > } > > cc -o a a.c > > ./a > malloc 0 returns 0x800 > > if you look at the source this is indeed clear - internally the 0x800 > is ZEROSIZEPTR and is set when a zero length is passed to malloc() > unless you have malloc_sysv set.Right, it passed you a pointer to which you may write 0 bytes to; exactly what the program asked for :) The FreeBSD 6.x behaviour is slightly against POSIX rules that state all successful malloc calls must return unique pointers, so the 7.x malloc silently rounds zero-size mallocs to 1. Ideally malloc would return unique pointers to blocks of memory set to MPROT_NONE via mprotect() (you could fit 8192 of these pointers in an 8k page), to prevent applications from using that byte of memory. -- Dan Nelson dnelson@allantgroup.com
In the last episode (Dec 11), Dan Nelson said:> In the last episode (Dec 11), Luigi Rizzo said: > > i was debugging a program on FreeBSD 6, and much to my surprise, i > > noticed that malloc(0) returns 0x800, as shown by this program: > > > > > more a.c > > #include <stdio.h> > > int main(int argc, char *argv[]) > > { > > char *p = malloc(0); > > printf(" malloc 0 returns %p\n", p); > > } > > > cc -o a a.c > > > ./a > > malloc 0 returns 0x800 > > > > if you look at the source this is indeed clear - internally the 0x800 > > is ZEROSIZEPTR and is set when a zero length is passed to malloc() > > unless you have malloc_sysv set. > > Right, it passed you a pointer to which you may write 0 bytes to; > exactly what the program asked for :) > > The FreeBSD 6.x behaviour is slightly against POSIX rules that state > all successful malloc calls must return unique pointers, so the 7.x > malloc silently rounds zero-size mallocs to 1. Ideally malloc would > return unique pointers to blocks of memory set to MPROT_NONE via > mprotect() (you could fit 8192 of these pointers in an 8k page), to > prevent applications from using that byte of memory.Also note that the 0x800 behaviour was added to malloc.c rev 1.60 back in 2001, which means that all of the 5.x and 6.x releases did this. -- Dan Nelson dnelson@allantgroup.com