[vox-tech] malloc() is ... old school?

Micah J. Cowan vox-tech@lists.lugod.org
Fri, 21 Mar 2003 10:21:17 -0800


On Thu, Mar 20, 2003 at 04:52:15PM -0800, Tim Riley wrote:
> 
> 
> "Micah J. Cowan" wrote:
> 
> > On Thu, Mar 20, 2003 at 10:15:43AM -0800, Tim Riley wrote:
> > >
> > >
> > > > The first library had malloc(). Always
> > > > using calloc() would be a ridiculously inefficient way to obtain
> > > > memory if you're going to just set it again anyway.
> > >
> > > It might seem inefficient to set memory twice, but you're looking
> > > at it from the CPU's point of view. Instead, by looking at it from
> > > the programmer's point of view, the extra nanoseconds it takes
> > > to always get a clean data structure is worth hours of time savings
> > > by not having to trace a core dump.
> >
> > You're saying that you'd rather have your program silently set the
> > wrong memory location than to vomit? In my experience, the earlier in
> > the development stage you catch a bug, the better.
> >
> > What situation are you thinking of where an accidentally unset,
> > malloc()ed structure would cause a core dump upon access that would
> > not be duplicated had calloc() been used?
> 
> The vulnerability with malloc() occurs when working with pointers.
> It's common to test if a pointer has been set
> by placing it inside an "if" statement before referencing it.
> If you always use calloc(), all of your pointers will be
> initialized with zero.

All bits zero != NULL. This is a common misbelief, which happens to be
true on a number of platforms. But it is not guaranteed to be true,
and is not on several platforms, though I conced that they are not the
mainstream. See: 

  Sec. 5 of the C FAQ: ~http://www.eskimo.com/~scs/C-faq/s5.html

  Any number of comp.lang.c posts:
    http://groups.google.com/groups?as_q=NULL%20calloc%28%29&as_ugroup=comp.lang.c

  Especially this one by the author of the FreeBSD C Library (last paragraph):
    http://groups.google.com/groups?q=NULL+calloc()+group:comp.lang.c+author:Chris+author:Torek&selm=18764%40dog.ee.lbl.gov

> For the following example
> it's clear that a core dump might occur; however, if the program were
> 1000 lines long and the variables set in different locations, tracing
> could be a bear.
> 
> typedef struct
> {
>     char *name;
>     char *address;
>     char *city;
>     char *state;
>     char *zip_code;
> } PERSON;
> 
> int main( int argc, char **argv )
> {
>     PERSON *person = malloc( sizeof( PERSON ) );
> 
>     person->name = "fred";

A core dump could occur right here, with or without calloc(),
considering you didn't check malloc()'s return.

>     if ( person->name && person->zip_code )
>     {
>         printf( "For person = %s, got zip code = %s\n",
>                 person->name, person->zip_code );
>     }
> }
> 
> If calloc() had been used, no one would have noticed the delay and no
> core would be dumped.

Provided that one is using a system on which NULL happens to be
all-bits-zero. Which we all are on this list, but can we guarantee
that the code you write won't be ported to such a system?

And I submit that without the core dump, the bug of having forgotten
to set *person's fields just got much, much harder to track down.

-Micah