#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... :)