More 2D array woes...

Steve Summit scs at adam.mit.edu
Tue Mar 5 10:33:38 AEST 1991


In article <1991Mar4.064805.22220 at nntp-server.caltech.edu> eychaner at suncub.bbso.caltech.edu writes:
>Some poeple have complained that this is in the FAQ; well, I did read the
>FAQ beforehand and the solutions it gives either result in a non-contiguous
>array or make it VERY DIFFICULT to make the array larger.  The following
>solution is MUCH better (though a little more opaque) than the ones in the
>FAQ, and IMHO should be included there.
[detailed solution omitted]
>>so you CAN do it in C.  It's just a little tricky.  Ok, a LOT tricky.
>Also, I would like to point out that to call realloc (to add a new row to 
>the array) with a function could be (I HOPE I got this right, PLEASE):
>      *array = (char (*)[N]) realloc (*array, ++(*num_of_elements) * N);

You also need a (char *) or (void *) cast before the *array
argument to realloc.  (Strictly speaking, the second argument
needs to be a size_t, either by declaring *num_of_elements or N that
way, or by using another cast.)

>This is VERY powerful, and is MUCH better than the FAQ answer.  It is also
>EXACTLY what I wanted.  So the FAQ is not the be-all and end-all of C.

My humble apologies.  I hope the FAQ list was not misrepresented
to you.  Note, by the way, that it does tend to shy rather
deliberately away from tricky and/or opaque solutions.

As it happens, my working copy of the FAQ list has for some time
contained a note to myself that something like the proposed
technique could be used ("with vicious enough casts").  The
technique is not entirely unknown to me; omitting to mention it
was a deliberate choice, based on the observations that:

     1.	pointers to arrays can be confusing, and in fact other
	parts of the list recommend avoiding them, and

     2.	the suggested technique only works if one dimension -- and
	specifically, the "length" of one "row," or the "width"
	of the array -- remains constant, while only the overall
	"length" (number of "rows") varies.

I am not at all sure that an FAQ list answer based on the
declaration

	char (*dynamic)[N];

would not bring up more questions than it answered.

I've never felt that the need for a dynamically allocated
two-dimensional array with one dimension constant led to that
frequent a question, and I also don't think that reallocation of
a "dope vector" array (which lets you reallocate along either
dimension) is terribly difficult.  (To be sure, the FAQ list does
not present code for doing so.)

However, if dynamically allocating a pointer to a constant-width
array is in fact considered a mainstream technique, I can
certainly add it to the list.  (Send your suggestions by mail,
please; there's no need to discuss this on the net.)

                                            Steve Summit
                                            scs at adam.mit.edu

P.S. Here's how I reallocate "dope vector" arrays.  It's a little
verbose, but hardly difficult or obscure.

	int **array = NULL;
	int xdim = 0;
	int ydim = 0;

	/* now reallocate to new dimensions newxdim, newydim */

	for(i = newydim; i < ydim; i++)		/* only if newydim < ydim */
		free((char *)array[i]);

	array = (int **)realloc((char *)array, newydim * sizeof(int *));

	for(i = ydim; i < newydim; i++)		/* only if newydim > ydim */
		array[i] = NULL;

	for(i = 0; i < newydim; i++)
		array[i] = (int *)
			realloc((char *)array[i], newxdim * sizeof(int));

	xdim = newxdim;
	ydim = newydim;

Note that, as written, this does depend on a "new" realloc,
i.e. one that can handle null pointers.



More information about the Comp.lang.c mailing list