[comp.lang.c] malloced structure initilization

bjm@sabin.UUCP (Brendan J. McMahon) (02/09/89)

/*
Simple problem - 
How do you initialize memory malloced for a structure without using calloc,
and without initilizing each structure element explicitly?
Example --
*/

#include <stdio.h>
#include <malloc.h>

struct foo{
    int a;
    long b;
    char c[80];
    double d;
};

main()
{
    struct foo *fooptr;

    if ( (fooptr=(struct foo *)malloc(sizeof(struct foo))) == NULL){
              puts("Malloc Bombed");
              exit(-1);
    }

    func(fooptr);
}

func(fooptr)
    struct foo *fooptr;
{
    struct foo *fp2;

    for(fp2=fooptr; fp2 < fooptr + sizeof(struct foo);  fp2++)
             *fp2=NULL;  /* Error - incompatible types */

}

djones@megatest.UUCP (Dave Jones) (02/10/89)

A small nit.  If you want to follow standard English style, the
past tense of "to malloc" is "mallocked". 

"Malloced" would be pronounced mal'-oasd.

C.f. "panicked", "picnicked", "picnicking", etc..

khera@romeo.cs.duke.edu (Vick Khera) (02/10/89)

In article <202@sabin.UUCP> bjm@sabin.UUCP (Brendan J. McMahon) writes:
>How do you initialize memory malloced for a structure without using calloc,
>and without initilizing each structure element explicitly?
>
>struct foo{
>    int a;
>    long b;
>    char c[80];
>    double d;
>};
 [..... some code omitted ...]
>func(fooptr)   struct foo *fooptr;
>{   struct foo *fp2;
>    for(fp2=fooptr; fp2 < fooptr + sizeof(struct foo);  fp2++)
							 ^^^^^^
this statement increments fp2 to point to the next struct foo, not to the
next byte in struct foo as pointed to by fp2, as this example seems to
want. why not just use
 bzero((char *)fooptr, sizeof(struct foo))
to zero out the structure.  besides, what's wrong with calloc()? have I
missed some point you were trying to make here?

>             *fp2=NULL;  /* Error - incompatible types */
>}


=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
ARPA:	khera@cs.duke.edu		Department of Computer Science
CSNET:	khera@duke        		Duke University
UUCP:	decvax!duke!khera		Durham, NC 27706

henry@utzoo.uucp (Henry Spencer) (02/10/89)

In article <202@sabin.UUCP> bjm@sabin.UUCP (Brendan J. McMahon) writes:
>How do you initialize memory malloced for a structure without using calloc,
>and without initilizing each structure element explicitly?

You can try using bcopy() or memset() (Berklix and SysV respectively), but
beware that things like pointers and floating-point numbers are *not*
guaranteed to be initialized to anything sensible that way.  The only way
to reliably initialize such things to specific values (like, say, NULL
or 0.0) is to do member-by-member initialization.  The bit patterns for
NULL and 0.0 are not guaranteed to be all zeros.
-- 
The Earth is our mother;       |     Henry Spencer at U of Toronto Zoology
our nine months are up.        | uunet!attcan!utzoo!henry henry@zoo.toronto.edu

ark@alice.UUCP (Andrew Koenig) (02/10/89)

In article <202@sabin.UUCP>, bjm@sabin.UUCP (Brendan J. McMahon) writes:

> Simple problem - 
> How do you initialize memory malloced for a structure without using calloc,
> and without initilizing each structure element explicitly?
> Example --

> #include <malloc.h>

> struct foo{
>     int a;
>     long b;
>     char c[80];
>     double d;
> };

How about this?

	static struct foo init_foo;
	struct foo *fp;
	fp = (struct foo *) malloc (sizeof (struct foo));
	*fp = init_foo;

init_foo is guaranteed to be initialized because it's static.
-- 
				--Andrew Koenig
				  ark@europa.att.com

gwyn@smoke.BRL.MIL (Doug Gwyn ) (02/10/89)

In article <202@sabin.UUCP> bjm@sabin.UUCP (Brendan J. McMahon) writes:
>How do you initialize memory malloced for a structure without using calloc,
>and without initilizing each structure element explicitly?

Copy a preinitialized (static) structure onto the freshly allocated one.
In modern C this can be done with a single assignment expression.

scjones@sdrc.UUCP (Larry Jones) (02/11/89)

In article <202@sabin.UUCP> bjm@sabin.UUCP (Brendan J. McMahon) writes:
>How do you initialize memory malloced for a structure without using calloc,
>and without initilizing each structure element explicitly?

Well, if your C compiler isn't an antique the easiest thing to do
is have a static instance of the structure which is properly
initialized and just assign it to the malloc-ed one.  (If you do
have an antique compiler, you could always use memcpy to do the
assignment.)

In article <13480@duke.cs.duke.edu>, khera@romeo.cs.duke.edu (Vick Khera) writes:
> why not just use
>  bzero((char *)fooptr, sizeof(struct foo))
> to zero out the structure.  besides, what's wrong with calloc()? have I
> missed some point you were trying to make here?

The reason for not using bzero or calloc is that all zero bit
doth not a zero make.  In particular, zeroing a pointer is not
guaranteed to make it null, nor is zeroing a floating value
guaranteed to make it 0.0.

----
Larry Jones                         UUCP: uunet!sdrc!scjones
SDRC                                      scjones@sdrc.UU.NET
2000 Eastman Dr.                    BIX:  ltl
Milford, OH  45150                  AT&T: (513) 576-2070
"When all else fails, read the directions."

glasser@madnix.UUCP (Daniel Glasser) (02/12/89)

If you need to initialize a structure allocated by a call to malloc()
the best way to go about it is (for most modern compilers):

{
	struct foreign *x;

	if ((x = malloc(sizeof(*x))) == NULL)
		panic("can't allocate...");
	else
		memset(x, 0, sizeof(*x));
	...
}

A good C library will have a version of memset which is optimal for the
hardware on which the program runs.  Some compilers turn this into an
in-line operation.  Another alternative is to do the zeroing in a loop.


-- 
-------------------------------------------------------------------------------
Daniel A. Glasser -- One of those things that goes "BUMP! (ouch)" in the night.
glasser@madnix or ...!uwvax.wisc.edu!per2!dag or ...!uwvax.wisc.edu!persoft!dag

bright@Data-IO.COM (Walter Bright) (02/14/89)

In article <8894@alice.UUCP< ark@alice.UUCP (Andrew Koenig) writes:
<In article <202@sabin.UUCP<, bjm@sabin.UUCP (Brendan J. McMahon) writes:
<< How do you initialize memory malloced for a structure without using calloc,
<< and without initilizing each structure element explicitly?
<How about this?
<	static struct foo init_foo;
<	struct foo *fp;
<	fp = (struct foo *) malloc (sizeof (struct foo));
<	*fp = init_foo;
<init_foo is guaranteed to be initialized because it's static.

Yah, and init_foo is guaranteed to be initialized to a 0 bit pattern,
just like if you called calloc instead of malloc. So where have you
gained anything here? I suggest that you declare init_foo something like:
	static struct foo init_foo = { 0,0L,0.0,(char *)0 };
or whatever is appropriate to the struct members.

bright@Data-IO.COM (Walter Bright) (02/14/89)

In article <489@madnix.UUCP> glasser@madnix.UUCP (Daniel Glasser) writes:
<If you need to initialize a structure allocated by a call to malloc()
<the best way to go about it is (for most modern compilers):
<	struct foreign *x;
<	if ((x = malloc(sizeof(*x))) == NULL)
<		panic("can't allocate...");
<	else
<		memset(x, 0, sizeof(*x));

Not true. If what you want is a 0 bit pattern, the best way is:
	struct foreign *x;
	if ((x = (struct foreign *) calloc(sizeof(*x),1)) == NULL)
		panic("can't allocate...");
calloc is a standard function, and is more commonly available than memset.

jimp@cognos.uucp (Jim Patterson) (02/15/89)

In article <1874@dataio.Data-IO.COM> bright@dataio.Data-IO.COM (Walter Bright) writes:
>In article <8894@alice.UUCP< ark@alice.UUCP (Andrew Koenig) writes:
><In article <202@sabin.UUCP<, bjm@sabin.UUCP (Brendan J. McMahon) writes:
><	static struct foo init_foo;
><init_foo is guaranteed to be initialized because it's static.
>Yah, and init_foo is guaranteed to be initialized to a 0 bit pattern,

Not so, according to the pANS C. See section 3.5.7:

  "If an object that has static storage duration is not
  initialized explicitly, it is initialized implicitly as if
  every member that has arithmetic type were assigned 0 and
  every member that has pointer type were assigned the null
  pointer constant"

As far as I know, on every known architecture supporting C the effect
is exactly the same anyways.

(Somebody, please correct me IF YOU KNOW OF A COUNTER EXAMPLE. I've
seen too many people say that it's not guaranteed by pANS C, which I
know, but I have not yet seen the name of a single machine or system
with a C compiler for which it isn't true).
-- 
Jim Patterson                              Cognos Incorporated
UUCP:decvax!utzoo!dciem!nrcaer!cognos!jimp P.O. BOX 9707    
PHONE:(613)738-1440                        3755 Riverside Drive
                                           Ottawa, Ont  K1G 3Z4

gwyn@smoke.BRL.MIL (Doug Gwyn ) (02/15/89)

In article <1874@dataio.Data-IO.COM> bright@dataio.Data-IO.COM (Walter Bright) writes:
>Yah, and init_foo is guaranteed to be initialized to a 0 bit pattern,

No, static storage is initialized to zero of the appropriate type,
which need not be a 0 bit pattern in all cases.  The first few C
implementations could use 0-bit fill for zeros of all types;
other implementations may need the compiler to do something special
to meet this requirement.

scjones@sdrc.UUCP (Larry Jones) (02/15/89)

In article <1874@dataio.Data-IO.COM>, bright@Data-IO.COM (Walter Bright) writes:
> In article <8894@alice.UUCP< ark@alice.UUCP (Andrew Koenig) writes:
> <init_foo is guaranteed to be initialized because it's static.
> 
> Yah, and init_foo is guaranteed to be initialized to a 0 bit pattern,
> just like if you called calloc instead of malloc. So where have you
> gained anything here? I suggest that you declare init_foo something like:
> 	static struct foo init_foo = { 0,0L,0.0,(char *)0 };
> or whatever is appropriate to the struct members.

dpANS requires statics to be initialized to zeros of the
appropriate type, not just zero bits.  I believe this is existing
practice.

----
Larry Jones                         UUCP: uunet!sdrc!scjones
SDRC                                      scjones@sdrc.UU.NET
2000 Eastman Dr.                    BIX:  ltl
Milford, OH  45150                  AT&T: (513) 576-2070
"When all else fails, read the directions."

friedl@vsi.COM (Stephen J. Friedl) (02/15/89)

In article <9649@smoke.BRL.MIL>, gwyn@smoke.BRL.MIL (Doug Gwyn ) writes:
> No, static storage is initialized to zero of the appropriate type,
> which need not be a 0 bit pattern in all cases.

For you chapter-and-verse fans out there, it's `3.5.7 Initialization'
under Semantics.

     Steve

-- 
Stephen J. Friedl        3B2-kind-of-guy            friedl@vsi.com
V-Systems, Inc.       I speak for you only      attmail!vsi!friedl
Santa Ana, CA  USA       +1 714 545 6442    {backbones}!vsi!friedl
--------Barbara Bush on... on... No, I just can't do it...--------

carlp@iscuva.ISCS.COM (Carl Paukstis) (02/17/89)

In article <9649@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
>In article <1874@dataio.Data-IO.COM> bright@dataio.Data-IO.COM (Walter Bright) writes:
>>Yah, and init_foo is guaranteed to be initialized to a 0 bit pattern,
>
>No, static storage is initialized to zero of the appropriate type,
>which need not be a 0 bit pattern in all cases.  The first few C
>implementations could use 0-bit fill for zeros of all types;
>other implementations may need the compiler to do something special
>to meet this requirement.

Now THIS is interesting!  As I remember, the original discussion was about
structures.  Does this mean that if I write:

  #include <stdio.h>

  static struct {
      float ward;
      int june;
      char wally;
      long beaver;
      double eddie;
      } mayfield;

  int main (int argc, char **argv)
  {
      printf("%f, %d, %c, %ld, %f\n",
            mayfield.ward, mayfield.june, mayfield.wally,
            mayfield.beaver, mayfield.eddie);
      return 0;
  }

I'm GUARANTEED (at least by the ANSI standard) to get (something like):

    0.0, 0, <NUL>, 0, 0.0

even on "unusual" architectures where zero-bit-pattern != 0?  Presumably
that means that any pointers I mention in the structure are also set to
proper nil pointers of appropriate type?

Specifically, does the initialization of static variables to "zero of the
appropriate type" apply to members of static structures?
-- 
Carl Paukstis    +1 509 927 5600 x5321  |"The right to be heard does not
                                        | automatically include the right
UUCP:     carlp@iscuvc.ISCS.COM         | to be taken seriously."
          ...uunet!iscuva!carlp         |                  - H. H. Humphrey

gwyn@smoke.BRL.MIL (Doug Gwyn ) (02/18/89)

In article <2363@iscuva.ISCS.COM> carlp@iscuva.ISCS.COM (Carl Paukstis) writes:
>Specifically, does the initialization of static variables to "zero of the
>appropriate type" apply to members of static structures?

Of course it does.  Also to first members of static unions, static
null pointers, etc.

guy@auspex.UUCP (Guy Harris) (02/18/89)

 >Does this mean that if I write:
 >
 >  #include <stdio.h>
 >
 >  static struct {
 >      float ward;
 >      int june;
 >      char wally;
 >      long beaver;
 >      double eddie;
 >      } mayfield;
 >
 >I'm GUARANTEED (at least by the ANSI standard) to get (something like):
 >
 >    0.0, 0, <NUL>, 0, 0.0
 >
 >even on "unusual" architectures where zero-bit-pattern != 0?

Yes (if <NUL> means '\0').

>Presumably that means that any pointers I mention in the structure are
>also set to proper nil pointers of appropriate type?

Yes.

>Specifically, does the initialization of static variables to "zero of the
>appropriate type" apply to members of static structures?

Yes.  From the May 13, 1988 dpANS:

	3.5.7 Initialization

	...

	  If an object that has static storage duration is not
	initialized explicitly, it is initialized implicitly as if every
	member that has arithmetic type were assigned 0 and every member
	that has pointer type were assigned a null pointer constant.