From: Robby on
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
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
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
> 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
> 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!

 |  Next  |  Last
Pages: 1 2 3
Prev: Memory allocation
Next: Postfix increment operator?