[comp.lang.lisp] Creating an array of structures

giant@lindy.Stanford.EDU (Buc Richards) (10/18/89)

When I make an array of structures, any changes to any of the elements
change all the elements.  What am I dong wrong?

Here is a simple case I ran on a NeXT and a MacII under Allegro Common
Lisp with the same results.

<cl> (defstruct cardtype
        card code)

CARDTYPE
<cl> (Setf tc (Make-array 25 :Element-type 'cardtype
        :Initial-element (make-cardtype)))

#(#s(CARDTYPE :CARD NIL :CODE NIL) #s(CARDTYPE :CARD NIL :CODE NIL) #s(CARDTYPE
:CARD NIL :CODE NIL) #s(CARDTYPE :CARD NIL :CODE NIL) #s(CARDTYPE :CARD NIL :CO
DE NIL) #s(CARDTYPE :CARD NIL :CODE NIL) #s(CARDTYPE :CARD NIL :CODE NIL) #s(CA
RD TYPE :CARD NIL :CODE NIL) #s(CARDTYPE :CARD NIL :CODE NIL) #s(CARDTYPE :CARD
 NIL :CODE NIL) ...)
<cl> (Setf (cardtype-code (Aref tc 1)) 360)

360
<cl> tc

#(#s(CARDTYPE :CARD NIL :CODE 360) #s(CARDTYPE :CARD NIL :CODE 360) #s(CARDTYPE
:CARD NIL :CODE 360) #s(CARDTYPE :CARD NIL :CODE 360) #s(CARDTYPE :CARD NIL :CO
DE 360) #s(CARDTYPE :CARD NIL :CODE 360) #s(CARDTYPE :CARD NIL :CODE 360) #s(CA
RD TYPE :CARD NIL :CODE 360) #s(CARDTYPE :CARD NIL :CODE 360) #s(CARDTYPE :CARD
NIL :CODE 360) ...)


----------------

Every element has the :code changed to 360.  Thanks for any assistance.

        Rob Richards                              @ @
        Stanford University                        -

mesard@bbn.com (Wayne Mesard) (10/20/89)

giant@lindy.Stanford.EDU (Buc Richards) writes:
>When I make an array of structures, any changes to any of the elements
>change all the elements.  What am I dong wrong?
[...]
><cl> (Setf tc (Make-array 25 :Element-type 'cardtype
>        :Initial-element (make-cardtype)))

MAKE-CARDTYPE gets called once and only once.  Every element in the
array then contains a pointer to the ONE structure which was created.
Changing one changes them all because they are one and the same.

:INITIAL-ELEMENT probably isn't what you want.  Try :INITIAL-CONTENTS.
E.g.:

 (Setf tc (Make-array 25 :Element-type 'cardtype
         :Initial-contents
	(do ((i 25 (1- i))
	     (lis nil (cons (make-cardtype) lis)))
	    ((zerop i) lis))))


Disclaimer: The DO may or may not be the politically correct way to cons
	    up the list.

Wayne();