Discussion:
"PORTING C" > 2 dim arrays?
(too old to reply)
Robby
2010-05-29 18:15:01 UTC
Permalink
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
Tim Roberts
2010-05-29 19:14:43 UTC
Permalink
Post by Robby
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
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.
Post by Robby
Also, is casting from a long pmr[][5] to a long pointer the right thing to
That should work, but I think the &pmr[0][0] is more expressive.
--
Tim Roberts, ***@probo.com
Providenza & Boekelheide, Inc.
Robby
2010-05-29 21:13:01 UTC
Permalink
Post by Tim Roberts
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].
Post by Tim Roberts
Post by Robby
Also, is casting from a long pmr[][5] to a long pointer the right thing to
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.
Igor Tandetnik
2010-05-29 19:27:29 UTC
Permalink
Post by Robby
===============================
#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?
Post by Robby
}lb;
lb* LB_create_lb (long pmr[][5])
Note how you specify one dimension here.
Post by Robby
If we want the address of the innitial location of pmr, then we can do
pmr OR &pmr[0][0]
pmr has the type long(*)[5], not long*. &pmr[0][0] would make the assignment work.
Post by Robby
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
Robby
2010-05-29 21:25:01 UTC
Permalink
Post by Robby
===============================
#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!
Igor Tandetnik
2010-05-29 22:00:36 UTC
Permalink
Post by Robby
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 ????
Yes, I believe it should. You can easily determine that experimentally.
Post by Robby
Post by Igor Tandetnik
How do you plan to use this pmr pointer later?
void func1(lb *pObj, long memOffset, long rm)
{
long *p, t;
p = pObj->pmr;
t = *(p+(memOffset + rm));
So you basically treat it as a regular flat one-dimensional array. What's the point of all this song and dance around 2d arrays, then?
--
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
Robby
2010-05-30 16:13:01 UTC
Permalink
Hello Igor,
Post by Igor Tandetnik
Post by Robby
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 ????
Yes, I believe it should. You can easily determine that experimentally.
I tried it but generates errors....Here is what I tried:
===================================
#include <stdio.h>
#include <malloc.h>

typedef struct tag_lb {
long pmr(*)[5];
}lb;

lb* LB_create_lb (long pmr[][5])
{
lb *obj_lb = NULL;
obj_lb = (lb*) malloc(sizeof (struct tag_lb));
obj_lb->pmr = pmr;
return obj_lb;
}

// GLOBAL PROPERTIES MESSAGE RECIPIES
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;
}
================================

here are some of the errors:

1>c:\_dts_programming\pic\_microchip_issues\simulated in
vc++\arrays_2dim\arrays_2dim\arrays_2dim\test2.cpp(8) : error C2059: syntax
error : '*'

1>c:\_dts_programming\pic\_microchip_issues\simulated in
vc++\arrays_2dim\arrays_2dim\arrays_2dim\test2.cpp(8) : error C2090: function
returns array
typedef struct tag_lb {
long pmr(*)[5]; <<<<< error points here!
}lb;

and the following error:
1>c:\_dts_programming\pic\_microchip_issues\simulated in
vc++\arrays_2dim\arrays_2dim\arrays_2dim\test2.cpp(15) : error C2659: '=' :
function as left operand

points to this line:
obj_lb->pmr = pmr;
Post by Igor Tandetnik
So you basically treat it as a regular flat one-dimensional array. What's the point >of all this song and dance around 2d arrays, then?
Whats the big deal? Everything can be done in one regular flat single array
too. I can do a program about a rubics cube and assign every square to a
single dimmension array and make sure I offset my data correctly... no? Using
a 2 or 3 dim array further structures your data. So, I figured it would give
a little more structure to my numerical list of 5 numbers each..... and also
gives me a chance to experiment with double dimension arrays. I don't see the
harm in that.

All help appreciated!

Robert
Igor Tandetnik
2010-05-30 16:38:03 UTC
Permalink
Post by Robby
===================================
#include <stdio.h>
#include <malloc.h>
typedef struct tag_lb {
long pmr(*)[5];
long (*pmr)[5];
--
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
Robby
2010-05-30 17:58:01 UTC
Permalink
Post by Igor Tandetnik
long (*pmr)[5];
wow. I never saw this... but makes sence. Thanks Igor.. I will sure miss
this site when it will close down.

Kindest regards
Roberto
Igor Tandetnik
2010-05-30 23:08:56 UTC
Permalink
Post by Robby
wow. I never saw this... but makes sence. Thanks Igor.. I will sure miss
this site when it will close down.
Come on over to

http://social.msdn.microsoft.com/Forums/en-US/vclanguage/threads

(not that I like it any more than you do).
--
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
Robby
2010-05-31 15:31:01 UTC
Permalink
Post by Igor Tandetnik
Come on over to
http://social.msdn.microsoft.com/Forums/en-US/vclanguage/threads
Will definitely do.

Personally, I liked the MS newsgroups, it felt like we posted questions to a
bunch progrramming pro's who were happy to help.... I don't know how it will
be in the new forum?

Roberto

Loading...