gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

C/C++ > Typecasting multidimensional arrays

#18056 - poslundc - Fri Mar 19, 2004 10:02 pm

What I've done is declared a pool of memory for various shared purposes. It is declared in my main module as follows:

Code:
u8      gMemoryPool[2048];


Just a simple array of 2048 bytes.

I would like to use this memory in another module as a 32x32 multidimensional array, preferably under a different name, so I would be able to refer to, say, map[10][7] and have it treat that as gMemoryPool[327]. I've tried using a macro:

Code:
#define      map      ((u8 [][32])gMemoryPool)


But this form of typecasting doesn't seem to work.

Anyone know how to typecast a multidimensional array? Or otherwise accomplish what I am trying?

Thanks,

Dan.

#18057 - sajiimori - Fri Mar 19, 2004 10:07 pm

Multidimensional arrays in C are implemented as arrays of pointers to arrays, so you can't treat a flat array as a multidimensional array. You have to use multiplication or shifting.
Code:

#define map(x, y) (gMemoryPool[((y)<<5)+(x)])

#18060 - poslundc - Fri Mar 19, 2004 10:31 pm

sajiimori wrote:
Multidimensional arrays in C are implemented as arrays of pointers to arrays


What?! Since when? I've been programming C for over a decade; I'm sure someone would've told me this!

Dan.

#18062 - poslundc - Fri Mar 19, 2004 11:42 pm

OK, I figured out how to do this.

For anyone ever attempting anything similar:

Code:
#define map      ((u8 (*)[32])gMemoryPool)


You can then refer to map[row][column] as though it were an n x 32 two-dimensional array.

And for the record, C does interpret multidimensional arrays as linear arrays.

Dan.

#18063 - sajiimori - Fri Mar 19, 2004 11:50 pm

Is that right? I wonder where I got my idea. Maybe from C# and all that.

In any case, the compiler has to produce the shift for you anyway, so there's not much of a difference...

Edit: If you have an array a[x][y], then a[i] returns a pointer to the i-th array, so that produces a bit of an illusion.

#18099 - beelzebub - Sat Mar 20, 2004 12:32 pm

Wouldn't a union be better...

typedef union uMEMORY_POOL_tag
{
u8 mRaw [2048];
u8 mMap [10][7];
} uMEMORY_POOL;


uMEMORY_POOL gMemoryPool;


Then you can access the map data as gMemoryPool.mMap [y][x] and you can add as many other pooled resources to the union as you want (front end screens and menus etc...), and still minimize memory usage.

#18101 - poslundc - Sat Mar 20, 2004 2:11 pm

A union would also work, except for a couple of things I don't like:

- the module containing the union has to know all of the possible uses for the pool, instead of other modules just using the module containing the pool

- you can't reference it as a single variable name, you have to reference it as an element of an object

Although in hindsight I could've done the union thing and then #defined my map variable as being gMemoryPool.mMap if I'd done it that way.

Still, I prefer it this way, so I don't have to keep a centralized list of the different ways that the pool is used.

Dan.

#18107 - Miked0801 - Sat Mar 20, 2004 5:44 pm

Cool, thanks for that. Always wondered how to do it... :)