Path: utzoo!news-server.csri.toronto.edu!cs.utexas.edu!uwm.edu!rpi!zaphod.mps.ohio-state.edu!think.com!mintaka!snorkelwacker.mit.edu!bloom-picayune.mit.edu!news From: scs@adam.mit.edu (Steve Summit) Newsgroups: comp.lang.c Subject: Re: More 2D array woes... Message-ID: <1991Mar5.003338.20486@athena.mit.edu> Date: 5 Mar 91 00:33:38 GMT References: <1002@caslon.cs.arizona.edu> <1991Mar4.030849.16054@nntp-server.caltech.edu> <1991Mar4.064805.22220@nntp-server.caltech.edu> Sender: news@athena.mit.edu (News system) Reply-To: scs@adam.mit.edu Organization: Thermal Technologies, Cambridge, MA Lines: 86 In article <1991Mar4.064805.22220@nntp-server.caltech.edu> eychaner@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@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.