Path: utzoo!mnetor!uunet!husc6!purdue!umd5!mimsy!chris From: chris@mimsy.UUCP (Chris Torek) Newsgroups: comp.lang.c Subject: Re: Allocating two dimensional arrays Message-ID: <10278@mimsy.UUCP> Date: 21 Jan 88 05:05:11 GMT References: <419@nikhefh.hep.nl> Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 103 [These attributions look vaguely suspicious, but are as they were in the parent article (do I *really* need to put in such disclaimers?)] >>Spencer@ogg.cgrg.ohio-state.edu (PROCEED) writes: >>>... how to dynamically allocate a two-dimensional >>>array of floats. (I have to have an N by N matrix of floats, but don't >>>know N beforehand.) >>#define malloc_matrix(p,n,m,t) ((p) = ((t) *) malloc((n)*(m)*sizeof(t))) >>#define matrix(p,n,m,x,y) ((p)[(n)*(x)+(y)]) In article <419@nikhefh.hep.nl> n62@nikhefh.hep.nl (Klamer Schutte) writes: >Why not simple something like this: > >struct matrix >{ float data[n][m]; >} *foo; > >... > >foo = ( struct matrix * )malloc( sizeof( struct matrix )); > >and accessing the data like: > >foo->data[n][m]; Why not indeed. Have you tried it? 1 f() 2 { 3 int n, m; 4 struct matrix { 5 float data[n][m]; 6 } *foo; 7 } xx.c, line 5: constant expected xx.c, line 5: constant expected >In this way the source code will reflect exactly how the data is accessed; >I think C programming should be done that way. As much as possible, certainly. But arrays must have all but the first dimension declared as a compile-time constant. The various previous solutions (which include vectors of vectors) will work. Incidentally, one solution I did not see is this: typedef float data_t; /* whatever we are storing in matrices */ /* (please change `data' to reflect the actual stuff) */ /* * Create an N by N matrix of data type data_t. * Return NULL if it cannot be made. */ data_t ** create_matrix(n) int n; { register data_t *mem; register data_t **rows; register int i; mem = (data_t *)malloc(n * n * sizeof(*mem)); if (mem == NULL) return (NULL); rows = (data_t **)malloc(n * sizeof(*rows)); if (rows == NULL) { free((char *)mem); return (NULL); } for (i = 0; i < n; i++) { rows[i] = mem; mem += n; } return (rows); } /* * Free such a matrix. Note that we need not know N. */ void free_matrix(mat) data_t **mat; { free((char *)*mat); free((char *)mat); } How it works, and how to modify it for M by N matrices, and for matrices of higher dimensionality, is left as an exercise for the reader. ===== Exercises: 1. How *does* it work? 2. Modify it to create a four-dimensional matrix of size W by X by Y by Z. 3. Modify it to produce upper or lower triangular matrices, without using any more calls to malloc, and without wasting space (no `mem' elements left over). -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris