Dynamically malloc()-able pointers in a struct?

chuck chuck at Morgan.COM
Thu Dec 29 02:25:46 AEST 1988


In article <448 at blake.acs.washington.edu> phaedra at blake.acs.washington.edu (J. Anderson) writes:
>
>	I have a small C syntax problem.  Given I have a structure of
>with the following nature:
>
>struct xyzzy {
>	int plugh;
>	long black_rod;
>	char *foobar;	/* This wants to be a pointer to a variable-length
>			 * array
>			 */
>}
>	I have tried various means of doing a malloc which _should_ (I
>think?) assign a memory value to foobar, but to no avail.  K&&R
>doesn't have a lot to say on this subject, nor does volume 5 of the
>Unix Programmer's Reference manual.  Is there a way to accomplish what
>I wish to do, or have I found a minor limitation in C?
>

I have two interpretations of the problem and therefore 2 answers.

1) The first is the most obvious:

  struct xyzzy dumb;
	    :
  dumb.foobar = malloc(N_NUMBER_OF_CHARS);

This allocates however many bytes you want for the foobar member to point to.
You can easily reallocate using realloc().

2) If you want to allocate the structure and the variable size foobar member
in 1 shot, try changing the struct definition as follows:

  struct xyzzy {
    int plugh;
    long black_rod;
    char foobar[1];	/* The bytes for foobar are contiguous
			 * with the rest of the structure
			 */
  };

Now, if you want to allocate a struct xyzzy with N_ELEMENTS
elements in the foobar array, do the following:

  struct xyzzy *dump;
	    :
  dump = (struct xyzzy *)malloc(sizeof(*dump) + (N_ELEMENTS-1) * sizeof(char));

This allocates the enough memory to hold the structure (sizeof(*dump)) plus
the remaining elements of foobar ((N_ELEMENTS-1) * sizeof(char)).  In fact
on many machines which promote allcoations to longword boundaries this might
allocate a few extra bytes so further optimization can be achived by computing
the offset of foobar within the struct etc...  To reallocate the foobar
array the entire struct must be reallocated.

This technique is used by the System V message queue interface.  The msgbuf
struct is declared as:

  struct msgbuf {
    long	mtype;
    char	mtext[1];
  };

Zardoz Ocheret

-- 
+------------------+   Chuck Ocheret, Sr. Staff Engineer   +------------------+
| chuck at morgan.com |       Morgan Stanley & Co., Inc.      |  (212)703-4474   |
|   Duty now ...   |19th Floor, 1251 Avenue of the Americas| for the future.  |
+------------------+         New York, N.Y.  10020         +------------------+



More information about the Comp.lang.c mailing list