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