Indefinite-length array as member of struct: how?

Steve Summit scs at adam.pika.mit.edu
Tue Jul 11 13:19:54 AEST 1989


In article <321 at yetti.UUCP> asst-jos at yetti.UUCP (Jonathan) writes:
>I'm no guru...

Then perhaps you shouldn't post when you aren't sure of the answer.

>...but don't user
>	char string[]; 
>in your struct. Use
>	char *string;
>Remember that although by definition, the name of an array is a pointer
>to the array,

This definition is generally misleading, and only makes sense if
you understand arrays and pointers so well that the definition is
not needed.

>there are certain limitations. If I remember correctly, 
>you can't user the name of a declared as a pointer. namely
>	char string[SIZE];
>	*string = ....
>is invalid. 

There are limitations, but this is not one of them.  The principal
differences are that given

	char array[SIZE];
	char *string;

"array" can't be directly assigned to (that is,
	array = newptr;
is invalid; the members of the array can of course be assigned
to), and that sizeof(array) != sizeof(string) (in general).

In article <661 at kl-cs.UUCP> pc at cs.keele.ac.uk (Phil Cornes) writes:
>...dynamically sized structures are not supported in C
>and your solution to the problem won't work. Here is a piece of code you might
>try instead (when you include error checking):
>	nodeptr = (struct node *) malloc (sizeof(struct node)+strlen(data)+1);
>	strcpy ((char *)nodeptr+sizeof(struct node),data);
>	nodeptr->string = (char *)nodeptr+sizeof(struct node);

This is unnecessarily baroque, and no more guaranteed to work
than the original attempt at simulating a "dynamically sized
structure."  I usually implement them as follows, and I believe
that the pANS contains sufficiently detailed descriptions of
required structure behavior that this sort of thing will work.
(Structure punning of a similar sort was, as I recall,
fundamental to the usage advocated in Thomas Plum's book Reliable
Data Structures in C, and although the book predated X3J11C, the
techniques should still be valid.)

	#define INITIALALLOC 1

	struct node {
		struct node* next;
		char string[INITIALALLOC];
	} *nodeptr;

	nodeptr = (struct node *)malloc(sizeof(struct node) +
		strlen(data) - INITIALALLOC + 1);	/* + 1 for \0 */
	(void)strcpy(nodeptr->string, data);

The only real difference here is the use of sizeof (which many
others have suggested) and the macro INITIALALLOC which obviates
the need for a 0-sized array while documenting and coordinating
the adjustment required when allocating.

                                            Steve Summit
                                            scs at adam.pika.mit.edu



More information about the Comp.lang.c mailing list