Prev: Memory allocation
Next: Postfix increment operator?
From: Robby on 29 May 2010 14:15 Hello, I am porting my last module from the old MCU/compiler to the new MCU/compiler and this is the only module that uses a double dimensional array. Although this worked in the old compiler, now in the new one it doesn't quite work and not to mention I am still a little confused on how to go about assigning the innitial address of a two dimensional array to an element in a structure... see below. Here is a small example of the problem: =============================== #include <stdio.h> #include <malloc.h> typedef struct tag_lb{ long *pmr; //<I need innitial address of 2 dim array stored here! }lb; lb* LB_create_lb (long pmr[][5]) { lb *obj_lb = NULL; obj_lb = (lb*) malloc(sizeof (struct tag_lb)); obj_lb->pmr = pmr; //<<< problem here! return obj_lb; } long pmr[5][5] = { 195, 194, 193, 0, 0, 194, 193, 0, 0, 0, 195, 194, 193, 0, 0, 193, 194, 195, 91, 92, 195, 194, 193, 92, 91}; int main() { static lb *objLb1 = NULL; objLb1 = LB_create_lb(pmr); return 0; } ======================================== I am getting the following error: 1>c:\_dts_programming\pic\_microchip_issues\simulated in vc++\arrays_2dim\arrays_2dim\arrays_2dim\test1.cpp(14) : error C2440: '=' : cannot convert from 'long [][5]' to 'long *' If we want the address of the innitial location of pmr, then we can do this... right?: pmr OR &pmr[0][0] Also, is casting from a long pmr[][5] to a long pointer the right thing to do in this case? like this: typedef struct tag_lb{ long *pmr; }lb; lb* LB_create_lb (long pmr[][5]) { lb *obj_lb = NULL; obj_lb = (lb*) malloc(sizeof (struct tag_lb)); obj_lb->pmr = (long*) pmr; ///<<< Cast from long to long * return obj_lb; } For now I can't really change whats in the tag_lb structure since my code uses pmr as a long pointer everywhere in my program. Can someone confirm to me that the only thing I was missing is the cast? All help appreciated. Thanking all in advance! -- Best regards Roberto
From: Tim Roberts on 29 May 2010 15:14 Robby <Robby(a)discussions.microsoft.com> wrote: > >I am porting my last module from the old MCU/compiler to the new >MCU/compiler and this is the only module that uses a double dimensional >array. Although this worked in the old compiler, now in the new one it >doesn't quite work and not to mention I am still a little confused on how to >go about assigning the innitial address of a two dimensional array to an >element in a structure... see below. >... >If we want the address of the innitial location of pmr, then we can do >this... right?: > >pmr OR &pmr[0][0] C++ is more particular than C. "pmr" is compatible with a pointer to array of long, but not pointer to long. Your second suggestion is correct. >Also, is casting from a long pmr[][5] to a long pointer the right thing to >do in this case? like this: That should work, but I think the &pmr[0][0] is more expressive. -- Tim Roberts, timr(a)probo.com Providenza & Boekelheide, Inc.
From: Igor Tandetnik on 29 May 2010 15:27 Robby wrote: > Here is a small example of the problem: > =============================== > #include <stdio.h> > #include <malloc.h> > > typedef struct tag_lb{ > long *pmr; //<I need innitial address of 2 dim array stored here! The compiler needs to know at least one dimension to properly address a 2d array. Just a single long* isn't sufficient. How do you plan to use this pmr pointer later? > }lb; > > lb* LB_create_lb (long pmr[][5]) Note how you specify one dimension here. > If we want the address of the innitial location of pmr, then we can do > this... right?: > > pmr OR &pmr[0][0] pmr has the type long(*)[5], not long*. &pmr[0][0] would make the assignment work. > Also, is casting from a long pmr[][5] to a long pointer the right thing to > do in this case? That rather depends on what it is you are trying to achieve. Which, I can't help but notice, you've never explained. -- With best wishes, Igor Tandetnik With sufficient thrust, pigs fly just fine. However, this is not necessarily a good idea. It is hard to be sure where they are going to land, and it could be dangerous sitting under them as they fly overhead. -- RFC 1925
From: Robby on 29 May 2010 17:13 > C++ is more particular than C. "pmr" is compatible with a pointer to array > of long, but not pointer to long. Your second suggestion is correct. Yes, now I remember, for the way I passed pmr... then, the type of pmr = long pointer to the second dimension of [5] ..... its my little way of seeing it ... I guess! And therefore as Igor put it : long(*)[5]. > >Also, is casting from a long pmr[][5] to a long pointer the right thing to > >do in this case? like this: > > That should work, but I think the &pmr[0][0] is more expressive. I find doing this is cleaner: obj_lb->pmr = (long*) pmr; But doing this keeps me closer to array theory reminding me exactly where the address really comes from: obj_lb->pmr = &pmr[0][0]; So, in the end its a personal choice, right? Thanks Tim.
From: Robby on 29 May 2010 17:25
> Robby wrote: > > Here is a small example of the problem: > > =============================== > > #include <stdio.h> > > #include <malloc.h> > > > > typedef struct tag_lb{ > > long *pmr; //<I need innitial address of 2 dim array stored here! > The compiler needs to know at least one dimension to properly address a 2d >array. Just a single long* isn't sufficient. So what if I do this: typedef struct tag_lb{ long pmr(*)[5]; }lb; would the following assignment work? lb* LB_create_lb (long pmr[][5]) { lb *obj_lb = NULL; obj_lb = (lb*) malloc(sizeof (struct tag_lb)); obj_lb->pmr = pmr; //<<< Assignment ???? return obj_lb; } I didn't try this since I will do it the type cast way or the &pmr[0[5] way. However I am curious if we wanted to assign it as shown above.... is this possible ? Just asking. > How do you plan to use this pmr pointer later? Main would call func1... and do the following: void func1(lb *pObj, long memOffset, long rm) { long *p, t; p = pObj->pmr; t = *(p+(memOffset + rm)); //.... do other stuff with t... } Thanks Igor! |