spencer@ogg.cgrg.ohio-state.edu (PROCEED) (01/18/88)
Maybe this can't be done. Maybe I'm not thinking about it the right way. But I can't figure out 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.) Can anyone help me on this one? Thanks. -- "I'm growing older but not up..." Stephen Spencer, Graduate Student | The Computer Graphics Research Group | {cbosgd,ucbvax}!osu-cis!ogg!spencer The Ohio State University | spencer@ogg.cgrg.ohio-state.edu 1501 Neil Avenue, Columbus OH 43210 |
kurt@hi.unm.edu (Kurt Zeilenga) (01/18/88)
Spencer@ogg.cgrg.ohio-state.edu (PROCEED) writes: >Maybe this can't be done. Maybe I'm not thinking about it the right way. >But I can't figure out 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.) Can anyone help me on this one? Thanks. You can not allocate multi-dimensional arrays dynamically. However, you can do is something like: #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)]) where t = element type p = pointer to type n,m = dimensions x,y = indexes malloc_matrix() allocates the space and matrix() is used to pick the element. There are many similiar macros that will do the same thing, these ones may be an overkill. -- Kurt (zeilenga@hc.dspo.gov)
g-rh@cca.CCA.COM (Richard Harter) (01/18/88)
In article <22941@hi.unm.edu> kurt@hi.unm.edu (Kurt Zeilenga) writes: >Spencer@ogg.cgrg.ohio-state.edu (PROCEED) writes: >>Maybe this can't be done. Maybe I'm not thinking about it the right way. >>But I can't figure out 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.) Can anyone help me on this one? Thanks. > >You can not allocate multi-dimensional arrays dynamically. However, >you can do is something like: .... macros deleted .... I will defer the question of whether Kurt is correct or not to people more knowledgable in the arcana of C than I am. I don't know whether you can cast something as being a pointer to an N by N array where N is a variable. However a rather simple approach is to use an array of pointers, e.g. float **array; char *malloc(); /* No one forgets this declaration, right? */ int i; ..... array = (float **)malloc(N*sizeof(float *)); for (i=0;i<N;i++) array[i] = (float *)malloc(N*sizeof*float)); You can then reference array[i][j] just as though it were a two dimensional array. For most applications this is satisfactory and, in fact, likely to execute faster. This technique will not work if want to treat the array both as an N by N two dimensional array and as a N**2 length one dimensional array. (I.e. you want to exploit contiguity of storage.) No problem. float **arr2, *arr1, *tmp; char *malloc(); int i; ..... arr1 = (float *)malloc(N*N*sizeof(float)); arr2 = (float **)malloc(N*sizeof(float *)); tmp = arr1; for (i=0;i<N;i++) { arr2[i] = tmp; tmp += N; } All very simple minded, I'm sure, but it does the trick. -- In the fields of Hell where the grass grows high Are the graves of dreams allowed to die. Richard Harter, SMDS Inc.
gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/18/88)
In article <1050@ogg.cgrg.ohio-state.edu> spencer@ogg.cgrg.ohio-state.edu (PROCEED) writes: >But I can't figure out 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.) Can anyone help me on this one? Thanks. There are two parts to this. The actual memory allocation is the easy part. The hard part is deciding how your code is to access a matrix element. Since C does not support multi-dimensional arrays that don't have a compile-time constant for every dimension except the first, you cannot directly use C array subscript notation to access the data in a single "rectangular" allocated matrix. There are two solutions, one of them to allocate a one-dimensional array and perform the indexing arithmetic explicitly, using the matrix width, and the other solution is to allocate an extra array of "row vector pointers" then use double indexing. The first method is simpler but usually slower (because index arithmetic is slower than indirection). /* METHOD 1: */ float *matrix = (float *)malloc( M * N * sizeof(float) ); #define Matrix(i,j) matrix[(i)*N + (j)]; /* for convenience */ /* ... */ matrix_ij = Matrix(i,j); /* METHOD 2: */ float *data = (float *)malloc( M * N * sizeof(float) ); float **matrix = (float **)malloc( M * sizeof(float *) ); for ( i = 0; i < M; ++i ) matrix[i] = &data[i*N]; /* ... */ matrix_ij = matrix[i][j];
pmd@cbdkc1.ATT.COM (Paul Dubuc) (01/19/88)
In article <1050@ogg.cgrg.ohio-state.edu> spencer@ogg.cgrg.ohio-state.edu (PROCEED) writes: }Maybe this can't be done. Maybe I'm not thinking about it the right way. }But I can't figure out 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.) Can anyone help me on this one? Thanks. First allocate an array of N pointers to N arrays of floats, then allocate N arrays of N floats and assign the resulting pointers to the elements of the first array. float **fa; fa = (float **)calloc(N, sizeof(float *)); for(i=0;i<N;++i) fa[i] = (float *)calloc(N, sizeof(float)); Now "fa" is your matrix. When you want to free the space for(i=0;i<N;++i) free((char *)fa[i]); free((char *)fa); -- Paul Dubuc {ihnp4,cbosgd}!cbdkc1!pmd
daniel@sco.COM (daniel edelson) (02/02/88)
In article <22941@hi.unm.edu> kurt@hi.unm.edu (Kurt Zeilenga) writes: >Spencer@ogg.cgrg.ohio-state.edu (PROCEED) writes: >>But I can't figure out how to dynamically allocate a two-dimensional >>array of floats. (I have to have an N by N matrix of floats...) > >You can not allocate multi-dimensional arrays dynamically. However, This statement is wrong. Your example is itself allocating a multidimensional array dynamically. Perhaps what you intend to say is that you cannot allocate a multidimensional array in one statement. That is more nearly accurate. >you can do is something like: > >#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)]) > >where > t = element type > p = pointer to type > n,m = dimensions > x,y = indexes > >malloc_matrix() allocates the space and matrix() is used to pick the >element. >-- > Kurt (zeilenga@hc.dspo.gov) You cannot allocate an array of an anonymous aggregate type. However you can allocate an array of a named aggregate type. If your named type is a vector type, then allocating an array of them yields a multidimensional array. The other way of allocating multidimensional structures in C, since the language lacks parameterized multidimensional arrays, is to repeatedly allocate vectors for each dimension of the array. Something like this. /* Allocate an array of floats */ typedef float *floatp; /* A vector type */ typedef floatp *array; /* An array type */ array allocate(r,c) unsigned r,c; { int i; floatp *A; char *calloc(unsigned, unsigned); A=(floatp*)calloc(r,sizeof(floatp)); for (i=0; i<c; i++) A[i]=(float*)calloc(c,sizeof(float)); return(A); } This scheme is disadvantageous in that it takes time proportional to the number of rows to allocate the array. However, that is probably a trivial cost compared to operating on the array elements. Furthermore, this scheme easily generalizes to arrays of arbitrary dimension. The logical and appropriate extension of this is to make an array type a structure which contains its dimensions. This supports general, defensive and transparent programming. This mechanism also allows A[i] to refer to the i'th row of the array. When the array is allocated as a continuous block of memory, A[i] refers to the i'th element. This, of course, stems from C's linear storage mapping. -- uucp: {uunet|decvax!microsoft|ucbvax!ucscc|ihnp4|amd}!sco!daniel ARPA: daniel@sco.COM Inter: daniel@saturn.ucsc.edu-------------- pingpong: a dink to the right side with lots of top spin | Disclaimed | fishing: flies in morning and evening, day - spinners | as usual |