Dan Karron@UCBVAX.BERKELEY.EDU (04/14/91)
As promised, here is some sample code to demonstrate my problem.
My goal is to have a dynamically allocated array of pointers to the
base of an array of 3 floats and a dynamically allocated array of pointers
to the base of a 2x3 array of floats;
The results of compilation are at the end of the code. Cut out the
code and use this makefile defines:
CFLAGS = -g2
LDFLAGS= -lmalloc
-------------snip.c------------------------------------------snip.c------------
/* The goal here is to construct a list of pointers to
* the base of an array of 3 float and the base of
* a 2x3 array of floats */
#include "stdio.h"
#include "malloc.h"
typedef struct LineTag {
float EndPoints[2][3];
float PlaneNormals[2][3];
char LineName[100];
} Line;
typedef struct PointTag {
float Vertex[3];
char PointName[100];
} Point;
typedef struct WrapperTag {
Line *LinePointer;
Point *PointPointer;
} Wrapper;
main()
{
Wrapper *p,*q,*r;
float (**plane_list)[2][3];
float (**point_list)[3]; /* why so much indirection ?*/
printf("sizeof **plane_list=%d\n",sizeof(**plane_list)/sizeof(float));
printf("sizeof **point_list=%d\n",sizeof(**point_list)/sizeof(float));
plane_list=calloc(3,sizeof(float *)); /* how do you spec a pointer to an array ? */
point_list=calloc(3,sizeof(float *)); /* make three slots at this address for demo */
p=calloc(1,sizeof(Wrapper));
p->PointPointer=calloc(1,sizeof(Point));
point_list[0]= p->PointPointer->Vertex; /* put the base address of the vertex list at point_list slot 0 */
printf("p->PointPointer=%#x\n",point_list[0]); /* the addresses match... */
printf("point_list[0]=%#x\n",point_list[0]);
p->PointPointer->Vertex[0]=0.1; /* assign some values */
p->PointPointer->Vertex[1]=0.2; /* we should see the same values from point_list */
p->PointPointer->Vertex[2]=0.3;
printf("%d:(%#x)%f,(%#x)%f,(%#x)%f\n",0,&p->PointPointer->Vertex[0],p->PointPointer->Vertex[0],
&p->PointPointer->Vertex[1],p->PointPointer->Vertex[1],
&p->PointPointer->Vertex[2],p->PointPointer->Vertex[2]); /* verify addresses and values */
printf("%d:(%#x)%f,(%#x)%f,(%#x)%f\n",0,
&((*point_list[0])[0]),(*point_list[0])[0],
&((*point_list[0])[1]),(*point_list[0])[1],
&((*point_list[0])[2]),(*point_list[0])[2]); /* Huh ?? */
/* you fill in the rest */
p->LinePointer=calloc(1,sizeof(Line));
plane_list[0]=p->LinePointer->PlaneNormals;
p->LinePointer->PlaneNormals[0][0]=0.0;
p->LinePointer->PlaneNormals[0][1]=1.0;
p->LinePointer->PlaneNormals[0][2]=2.0;
p->LinePointer->PlaneNormals[1][0]=10.0;
p->LinePointer->PlaneNormals[1][1]=11.0;
p->LinePointer->PlaneNormals[1][2]=12.0;
q=calloc(1,sizeof(Wrapper));
q->LinePointer=calloc(1,sizeof(Line));
q->LinePointer->PlaneNormals[0][0]=100.0;
q->LinePointer->PlaneNormals[0][1]=101.0;
q->LinePointer->PlaneNormals[0][2]=102.0;
q->LinePointer->PlaneNormals[1][0]=1010.0;
q->LinePointer->PlaneNormals[1][1]=1011.0;
q->LinePointer->PlaneNormals[1][2]=1012.0;
r=calloc(1,sizeof(Wrapper));
r->LinePointer=calloc(1,sizeof(Line));
r->LinePointer->PlaneNormals[0][0]=0.10;
r->LinePointer->PlaneNormals[0][1]=1.10;
r->LinePointer->PlaneNormals[0][2]=2.10;
r->LinePointer->PlaneNormals[1][0]=10.10;
r->LinePointer->PlaneNormals[1][1]=11.10;
r->LinePointer->PlaneNormals[1][2]=12.10;
}
--cut.c-here-------------------------------------------------------------------
Here is what the compiler says:
karron:~/D.Bug:47make Bug
cc -g2 Bug.c -lmalloc -o Bug
ccom: Warning: Bug.c, line 38: Illegal pointer combination: pointer to array of
float versus pointer to float
point_list[0]= p->PointPointer->Vertex;
--------------------------------------^
ccom: Warning: Bug.c, line 59: illegal array size combination
plane_list[0]=p->LinePointer->PlaneNormals;
------------------------------------------^
karron:~/D.Bug:48Bug
sizeof **plane_list=6
sizeof **point_list=3
p->PointPointer=0x10006a10
point_list[0]=0x10006a10
0:(0x10006a10)0.100000,(0x10006a14)0.200000,(0x10006a18)0.300000
0:(0x10006a10)0.100000,(0x10006a14)0.200000,(0x10006a18)0.300000
Exit 200
What do you think it the way to do this ? I want to use arrays, not
float ***plane_list. Why ? Because the 2x3 array and the 1x3 array is
being used as a basic geometric object, and I want to be able to
print out the values in the debugger as a unit. My subroutines take
this 2x3 array as a basic unit, similar to the sgi typedef Matrix, which
is a 4x4 array of floats. Passing anything else should signal a compiler
error with prototype checking turned on. You can pass a float *,
but I want stronger typeing than that.
Cheers!
Dan.
| karron@nyu.edu (e-mail alias ) Dan Karron, Research Associate |
| Phone: 212 263 5210 Fax: 212 263 7190 New York University Medical Center |
| 560 First Avenue Digital Pager <1> (212) 397 9330 |
| New York, New York 10016 <2> 10896 <3> <your-number-here> |jit@slic.cellbio.duke.edu (Jit Keong Tan) (04/14/91)
In article <9104131716.AA09142@karron.med.nyu.edu> >Here is what the compiler says: >karron:~/D.Bug:47make Bug > cc -g2 Bug.c -lmalloc -o Bug > ccom: Warning: Bug.c, line 38: Illegal pointer combination: pointer to array of > float versus pointer to float > point_list[0]= p->PointPointer->Vertex; > --------------------------------------^ > ccom: Warning: Bug.c, line 59: illegal array size combination > plane_list[0]=p->LinePointer->PlaneNormals; > ------------------------------------------^ Usually if the compiler complains and that when I know I am right (needless to say this is very important) I just typecast them. It seems that your code is fine. This should be a bug in the compiler. Typecast the following to the lines that complains should keep the compiler happy. point_list[0]= (float (*)[3])p->PointPointer->Vertex; plane_list[0]=(float (*)[2][3])p->LinePointer->PlaneNormals; To avoid too many keystroke repetition, or any typing error, or to improve readability, (or to help my deficiencies about the above skills) I usually do the following: typedef float somename[2][3]; somename **plane_list; is probably easier to read than: float (**plane_list)[2][3]; -- -------------------------------------------------------- Jit Keong Tan | internet: jit@slic.cellbio.duke.edu (919) 684-8098 | bitnet : tan00001@dukemc.bitnet