[comp.lang.c] 2D array question

v8902477@cc.nu.oz.au (07/02/90)

	Hello,  could somebody please help me with the following? I'm attempting
to create a two dimensional array at run time using calloc.  The array is an
array of structures like this :

	struct a {
		int a1, a2, a3;
	};

And I'm using :

	array = (struct a *) calloc(xdim*ydim, sizeof(struct a));

to allocate space for the array.  xdim and ydim are the dimensions.  I believe
this correct.  It seems to work.  The problem came when I attempted to assign a
value to an element in the array.  I tried it this way :

	*((array+x+y*ydim).a1) = value;

Am I correct with this?  If array is a pointer it's okay to add integers to it
and use the sum as a pointer, is it not?  I get an error stating that .a1 is not
a valid lvalue.  Should I be using -> somewhere?

Help please!

Bernard.

Sorry if this has been asked before.

bernt@wolfen.cc.uow.oz (Bernt Ribbum) (07/02/90)

v8902477@cc.nu.oz.au writes:


>	Hello,  could somebody please help me with the following? I'm attempting
>to create a two dimensional array at run time using calloc.  The array is an
>array of structures like this :
>
>	struct a {
>		int a1, a2, a3;
>	};
>
>And I'm using :
>
>	array = (struct a *) calloc(xdim*ydim, sizeof(struct a));

(correct so far)
However,

>	*((array+x+y*ydim).a1) = value;

... is not correct. (array+x+y*ydim) is still a pointer and it is thus
not valid to reference a structure member of it (ie .a1).

However, (*(array+x+y*ydim)) is a structure, so 

	(*(array+x+y*ydim)).a1 = value;

may be used, or better still:

	(array+x+y*ydim)->a1 = value;

(See K&R 2nd Ed. ch.6.2, pp.129-132)

     _____
      )   )                    Bernt Ribbum, Dept. of Elec. & Comp. Eng.
     /___/  _   __ __  _/_         University of Wollongong, PO.Box 1144
    /    ) /_) /  /  ) /                  Wollongong NSW 2500, AUSTRALIA
 (_/____/ (___/  /  /_/                       bernt@wolfen.cc.uow.edu.au

hhp00389@uxa.cso.uiuc.edu (07/03/90)

In order for the previous examples to work correctly, you need to multiply
y by xdim, not by ydim.

Quincey Koziol
Programmer
NCSA

koziol@ncsa.uiuc.edu

zvs@bby.oz.au (Zev Sero) (07/03/90)

In article <3336.268f44b2@cc.nu.oz.au> v8902477@cc.nu.oz.au writes:

	struct a {
	    int a1, a2, a3;
	};
	array = (struct a *) calloc(xdim*ydim, sizeof(struct a));

and then
	*((array+x+y*ydim).a1) = value;
which doesn't work.



The following:
    (*(array + x + y * ydim)).a1 = value;
or
    (array + x + y * ydim)->a1 = value;
will work.  Adding to a pointer still yields a pointer.

However, try the following instead:
    array = (struct a **) malloc (ydim * sizeof (struct a *);
    for (i = 0; i < ydim; i++)
	array[i] = (struct a *) calloc (xdim, sizeof (struct a));
    ...
    array[y][x].a1 = value;

This will give you the almost-equivalent of declaring 
   struct a array[ydim][xdim];
which you would have done if ydim and xdim were constants.

The differences between the pointer and a proper 2d array are that the
pointer is modifiable, and that if you free the pointer you should
first free each element.  Also, the elements of an array occupy a
contiguous area of memory, and the elements of this pseudo-array might
not, but I don't see what difference that makes.
--
				Zev Sero  -  zvs@bby.oz.au
...but we've proved it again and again
that if once you have paid him the danegeld,
you never get rid of the Dane.		- Rudyard Kipling

johnsc@microsoft.UUCP (John SCHWABACHER) (07/04/90)

In article <6311@wolfen.cc.uow.oz> bernt@wolfen.cc.uow.oz (Bernt Ribbum) writes:
| 
| However, (*(array+x+y*ydim)) is a structure, so 
| 
| 	(*(array+x+y*ydim)).a1 = value;
| 
| may be used, or better still:
| 
| 	(array+x+y*ydim)->a1 = value;
| 

Or even better, 

	(array+x+y*xdim)->a1 = value;
		   ^