fano@lifia.UUCP (11/21/86)
forgive the ignorance of a novice C-programmer: I need advice on dynamic space allocation for multidimensionnal arrays: Here is a way I have implemented dynamic allocation for a 2 X 2 matrix named sig in a C-source file named combin1.c: (I'll explain further the reason why I'm not satisfied with that solution) BEGINNING OF THE EXAMPLE: float **sig; /* matrix declaration */ .... sig = (int *)malloc(n * sizeof(int)); /* allocates space for sig */ for ( i = 0; i < n; i++) /* lines adresse */ { sig[i] = (float *)malloc(n * sizeof(float));/* allocates space for */ } /* columns of line i */ .... for (i = n-1 ; i >= 0; i--) { free(sig[i]); /* desallocates space */ } free(sig); END OF THE EXAMPLE during the compiling time, I get the following warning: "combin1.c", line 220: warning: illegal pointer combination any-way the program runs, and gives the desired results. The compiler message suggests that I didn't use the proper way to implement matrix dynamic allocation. So, could someone over there give me advices for a cleaner solution. Thanx. -- fano rampa* /////////////////////////////////////////////////////////////////////////////// "Carmen lips are more exciting than Common lisp..." -G.Bizet- fano@lifia.UUCP or mcvax!lifia!fano
alastair@axis.UUCP (Alastair Adamson) (11/23/86)
In article <1046@lifia.UUCP> fano@lifia.UUCP (Rampa*) writes: > > float **sig; /* matrix declaration */ > .... > sig = (int *)malloc(n * sizeof(int)); /* allocates space for sig */ > >during the compiling time, I get the following warning: > "combin1.c", line 220: warning: illegal pointer combination Try changing the initialisation of sig to sig = (float **)malloc(n * sizeof(float *)); and the warning message will go away. Since sig is a double pointer to a float, that is what you want malloc to return. You are creating a dope vector, where each element of the vector is in fact a pointer a row which in turn is a pointer to the elements of that row; thus: --- ----------- | |------------>| | | |----- ----------- --- | | ----------- ------->| | ----------- The technique is common. Each element of the 2-dimensional table is float. Thus the pointer to each row is a (float *). Sig points to these row pointers ans is thus is (float **). By the way, another solution which uses less memory is simplt to get hold of enough space for all the elements of the table and do the addressing yourself. For example a N x M table can be dealt with: table = (type *)malloc(N * M * sizeof(type)); ... table[i * N + j] = value; /* put value in table[i][j] */ ... free((char *)table); /* free the space */ Alternatively, to make acceses *look* better, use #define Table(i, j) table[i * N + j] and Table(i, j) = value; Bonne chance, Alastair
throopw@dg_rtp.UUCP (Wayne Throop) (11/26/86)
> fano@lifia.UUCP (Rampa*) > I need advice on dynamic space allocation for multidimensionnal arrays: Well... a little maybe. > float **sig; /* matrix declaration */ > sig = (int *)malloc(n * sizeof(int)); /* allocates space for sig */ OK. Stop right here for a minute. What's wrong with this picture? It is a little subtle, perhaps, but a pointer value of type (int *) is being assigned to a pointer of type (float **). Does anybody really not see anything wrong with this? Hmmmmmm? Can you say "illegal pointer combination"? I knew you could. Lint can say it too. Let's say it together, boys and girls... (oh all right, I know I'm being nasty... I'll behave myself the rest of the posting, alright?) To fix this, make the allocation read: sig = (float **)malloc(n * sizeof(float *)); > sig[i] = (float *)malloc(n * sizeof(float)); /* allocate a column */ This one is already correct. > free(sig[i]); /* desallocates space */ Should be: free((char *)sig[i]); > free(sig); Should be: free( (char *)sig ); > during the compiling time, I get the following warning: > "combin1.c", line 220: warning: illegal pointer combination > any-way the program runs, and gives the desired results. The program will run correctly on systems where integers have the same length as pointers to float, and where pointers to float have the same format as pointers to char. I don't know what kind of system that would be. Maybe... oh, I don't know... could it be... *A* *VAX*???? (Isn't that special? :-) > The compiler message suggests that I didn't use the proper way to implement > matrix dynamic allocation. So, could someone over there give me advices for > a cleaner solution. In fact, the program seemed quite clean and well written already, except for the pointer type mismatches and the hidden assumption about the size of floats and ints. Fix that, and the program should still work, and lint will shut up also... who could ask for more? -- A programming language is low level when its programs require attention to the irrelevant. --- Alan J. Perlis -- Wayne Throop <the-known-world>!mcnc!rti-sel!dg_rtp!throopw
turk@apple.UUCP (Ken "Turk" Turkowski) (11/27/86)
>> fano@lifia.UUCP (Rampa*) >> I need advice on dynamic space allocation for multidimensionnal arrays: >> >> float **sig; /* matrix declaration */ >> sig = (int *)malloc(n * sizeof(int)); /* allocates space for sig */ There have been numerous responses to get the declarations consistent, so I won't belabor them here. However, I would like to point out the use of a function that can speed up the program considerably when you are only allocating temporary variables. The function is alloca(), and allocates memory from the stack, rather than from the heap. The result is that allocation is simpler, and vanishes automatically when you exit the routine. The purpose of alloca() is to compensate for the deficiency in C that does not allow you to do something like this: func(a, n) int *a, n; { int b[n+1]; /* <- C doesn't allow this */ . . . } by doing this: func(a, n) int *a, n; { int *b; b = (int *)(alloca((n+1) * sizeof(int))); . . . -- Ken Turkowski @ Apple Computer, Inc., Cupertino, CA UUCP: {sun,nsc}!apple!turk CSNET: turk@Apple.CSNET ARPA: turk%Apple@csnet-relay.ARPA
mlandau@Diamond.BBN.COM (Matt Landau) (11/27/86)
In newsgroup comp.lang.c (article <332@apple.UUCP>), turk@apple.UUCP (Ken "Turk" Turkowski) writes: > >There have been numerous responses to get the declarations consistent, so I >won't belabor them here. > >However, I would like to point out the use of a function that can speed up the >program considerably when you are only allocating temporary variables. The >function is alloca(), and allocates memory from the stack, rather than from >the heap. The result is that allocation is simpler, and vanishes automatically >when you exit the routine. Well, there are going to be a lot of people pointing this out, but I thought I'd be the first :-) Alloca is nonstandard, nonportable, and doesn't exist on a lot of machines. In fact, the last time this subject came up was when a lot of people were having trouble porting Gnu Emacs bacause it used alloca(). At the time, I think the conclusion was that there exist machine architectures for which it is practically impossible to even implement it. The bottom line: Don't use alloca if you expect your code to port. -- Matt Landau BBN Laboratories, Inc. mlandau@diamond.bbn.com 10 Moulton Street, Cambridge MA 02238 ...seismo!diamond.bbn.com!mlandau (617) 497-2429