Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!tut.cis.ohio-state.edu!bloom-beacon!bu-cs!dartvax!eleazar.dartmouth.edu!davidg From: davidg@eleazar.dartmouth.edu (David Gelhar) Newsgroups: comp.lang.c Subject: Re: Indefinite-length array as member of struct: how? Keywords: char string [] [0] [1] Message-ID: <14304@dartvax.Dartmouth.EDU> Date: 9 Jul 89 20:02:02 GMT References: <7360@c3pe.UUCP> <8870@venera.isi.edu> Sender: news@dartvax.Dartmouth.EDU Reply-To: davidg@eleazar.dartmouth.edu (David Gelhar) Organization: Dartmouth College, Hanover, NH Lines: 49 >In article <7360@c3pe.UUCP> charles@c3pe.UUCP (Charles Green) writes: >>I have an application where I'm building and manipulating a stack of >>variable-length strings. [...] >> >>struct node { >> struct node* next; >> char string[]; >>} *nodeptr; >> In article <8870@venera.isi.edu> lmiller@venera.isi.edu.UUCP (Larry Miller) writes: >[...] > > 2) This works because of a trick: the order in which fields in the > structure are declared. Simply changing the definition of a struct node > to: > struct node { > char string[]; > struct node* next; > }; > causes disaster. > > 3) Because of the indeterminate length of the string field in each > node, you can't pass a struct node to/from a function. All that gets > copied over will be the next field and, at best, one character from > the string field. >[...] 2) Isn't a very strong argument. K & R specifies that addresses are assigned in increasing order from left to right; as long as you DON'T change the definition order, disaster is avoided. The danger isn't that the compiler will do the wrong thing, rather that some later (and lesser :-)) programmer will not understand the significance of the ordering of the structure members. Situations like this are an excellent opportunity to try out a seldom-used feature of C -- the "comment". The obvious answer to 3) is to simply pass the address of the structure instead of the structure itself. Admittedly, this could be a limitation, but copying structures for a function call is expensive, so maybe you didn't want to do that anyway. :-) This is certainly a trick, and not one I'd use every day, but it could have its uses. For one thing, it requires only one malloc per element, while more straightforward methods (like putting a char * in the struct) require two. Depending on the malloc overhead (in terms of both internal fragmentation and execution time), it seems this could be a useful approach.