[comp.lang.c++] initializing array of objects

rpj@redcloud.cad.mcc.com (Rich Johns) (06/17/89)

class Foo;

Foo** fooArray;
fooArray = new Foo*[100];
for (int i = 0; i < 100; i++) fooArray[i] = 0;


Is there a better way to initialize fooArray?

Rich Johns, MCC CAD Program | 3500 W. Balcones Center Dr., Austin, TX 78759
ARPA: johns@mcc.com         | Phone: [512] 338-3714
UUCP: {uunet,harvard,gatech,pyramid}!cs.utexas.edu!milano!cadillac!johns

bright@Data-IO.COM (Walter Bright) (06/20/89)

In article <1284@cadillac.CAD.MCC.COM> rpj@redcloud.cad.mcc.com (Rich Johns) writes:
>class Foo;
>Foo** fooArray;
>fooArray = new Foo*[100];
>for (int i = 0; i < 100; i++) fooArray[i] = 0;
>Is there a better way to initialize fooArray?

Try:
	memset(fooArray,0,100 * sizeof(fooArray[0]));
or:
	fooArray = (Foo**) calloc(100,sizeof(fooArray[0]));
Both are faster and generate less code.

shankar@hpclscu.HP.COM (Shankar Unni) (06/21/89)

> bright@Data-IO.COM (Walter Bright) writes:
> In article <1284@cadillac.CAD.MCC.COM> rpj@redcloud.cad.mcc.com (Rich Johns) writes:
> >class Foo;
> >Foo** fooArray;
> >fooArray = new Foo*[100];
> >for (int i = 0; i < 100; i++) fooArray[i] = 0;
> >Is there a better way to initialize fooArray?
> 
> Try:
> 	memset(fooArray,0,100 * sizeof(fooArray[0]));
> or:
> 	fooArray = (Foo**) calloc(100,sizeof(fooArray[0]));
> Both are faster and generate less code.

And both are non-portable.

A NULL pointer does not have to have a bit-representation of all-zeroes.
Admittedly this is rare, but I do know of a couple of such machines.

"fooArray[i] = 0" initializes fooArray[i] to a NULL pointer value. 
"memset" and "calloc" initialize fooArray[*] to all-zero bits.

Try the following:

   memset (fooArray, (Foo *) 0, 100*sizeof(Foo *));

It's fast and correct.
----
Shankar Unni.

dfp@cbnewsl.ATT.COM (david.f.prosser) (06/23/89)

In article <1000015@hpclscu.HP.COM> shankar@hpclscu.HP.COM (Shankar Unni) writes:
>> bright@Data-IO.COM (Walter Bright) writes:
>> 
>> Try:
>> 	memset(fooArray,0,100 * sizeof(fooArray[0]));
>> or:
>> 	fooArray = (Foo**) calloc(100,sizeof(fooArray[0]));
>> Both are faster and generate less code.
>
>And both are non-portable.
>
>Try the following:
>
>   memset (fooArray, (Foo *) 0, 100*sizeof(Foo *));
>
>It's fast and correct.
>----
>Shankar Unni.

Sorry.  Your example is no better than the first use of memset().  The
function sets *bytes* to the value of the middle argument.  Unless the
machine uses the same value for each byte of a pointer, this won't work.

Try:
	static const Foo *empty[100];
	(void)memcpy(fooArray, empty, sizeof empty);
or
	static const struct foo100struct { Foo *array[100]; } empty;
	foo100struct *p;
	p = new foo100struct;
	*p = empty;
	fooArray = p->array;

Both of these suffer from fixed sizes and both rely on the default
initialization of pointers to null.

(Apologies for any C++ usage errors; I am in no way an expert.)

Dave Prosser

bright@Data-IO.COM (Walter Bright) (06/23/89)

In article <1000015@hpclscu.HP.COM< shankar@hpclscu.HP.COM (Shankar Unni) writes:
<< bright@Data-IO.COM (Walter Bright) writes:
<< In article <1284@cadillac.CAD.MCC.COM< rpj@redcloud.cad.mcc.com (Rich Johns) writes:
<< <class Foo;
<< <Foo** fooArray;
<< <fooArray = new Foo*[100];
<< <for (int i = 0; i < 100; i++) fooArray[i] = 0;
<< <Is there a better way to initialize fooArray?
<< Try:
<< 	memset(fooArray,0,100 * sizeof(fooArray[0]));
<< or:
<< 	fooArray = (Foo**) calloc(100,sizeof(fooArray[0]));
<< Both are faster and generate less code.
<And both are non-portable.
<A NULL pointer does not have to have a bit-representation of all-zeroes.
<Admittedly this is rare, but I do know of a couple of such machines.
<"fooArray[i] = 0" initializes fooArray[i] to a NULL pointer value. 
<"memset" and "calloc" initialize fooArray[*] to all-zero bits.
<
<Try the following:
<   memset (fooArray, (Foo *) 0, 100*sizeof(Foo *));
<It's fast and correct.

Not quite. memset will set fooArray to whatever the least significant
byte of (Foo*)0 turns out to be. Also, (Foo*)0 on the PC can turn out
to be 32 bits, while memset expects a 16 bit value.

I've been involved frequently with porting code between Vaxes, PCs,
68000s, 386s and Sparcs, running various operating systems. None of these
have problems with (void*)0!=0bits. Based on experience, I don't care
about:
	1. 1's complement machines
	2. NULL pointers are not 0 machines
	3. 0.0 is not a 0 bit pattern machines
	4. EBCDIC
I worry about *real* porting problems:
	1. 68000's store bytes in the wrong :-) order
	2. int's are different sizes
	3. Properly declaring functions that return pointers
	4. Whether chars are signed or unsigned
	5. Care in passing pointers, ints and longs as function parameters
	6. K&R compilers (no prototyping, etc.)
	7. Properly using varargs (it matters on RISC machines)
	8. Operating system variations
	9. Non-virtual memory machines
	10. Text vs binary file modes

Someday I may run across the mythical machine with 0!=NULL, but I doubt it.
I don't waste time porting code to machines that do not have significant
market presence.

When talking portability, there is 'more portable' and 'less portable'.
It usually isn't black and white as in 'portable' and 'not portable'.

shankar@hpcllca.HP.COM (Shankar Unni) (06/26/89)

> Try the following:
>    memset (fooArray, (Foo *) 0, 100*sizeof(Foo *));
> It's fast and correct.

Whoops! My brain must have been on hold the day I posted that. I was
thinking of something completely different.

Thanx to all those who have politely pointed out my whopper to me.
----
Shankar Unni.                           "A closed mouth collects no feet"