Archived

This topic is now archived and is closed to further replies.

PyroBoy

Dynamic Allocation Of 2D Arrays

Recommended Posts

I''m trying to dynamically allocate a 2D array of user-defined types, like so:

struct TILE2D
{
     BYTE type;
     float minTU;
     float minTV;
     float maxTU;
     float maxTV;
};

TILE2D *tileArray = NULL;
int tilesX = 30;
int tilesY = 30;

tileArray = new TILE2D[tilesY][tilesX];

 
The VC++6 compiler error I get is: error C2540: non-constant expression as array bound ...so I changed the last line to read:
tileArray = new TILE2D[30][30];
 
And I get this error: error C2440: ''='' : cannot convert from ''struct TILE2D (*)[30]'' to ''struct TILE2D *''. Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast What gives? I''m looking at an example in a book that allocates arrays in this fashion using new, but the compiler won''t play along... Anyone done this before?

Share this post


Link to post
Share on other sites
i just quickly glanced at your code and it seems you are creating a new (Your Struct) [Array][];
i dont know how you could make a variable equal to a struct
so instead of doing tilearray=new TILE2D[][]
make a variable with the structure of the TILE2D array. i hope that made sense.

Share this post


Link to post
Share on other sites
Hey. I tried out a different variation of that code and got the same result. I know i''ve done it that way before... but that was using Turbo C or something, i can''t remember. Anyway, here''s a way you COULD do it...

tileArray = new TILE2D[tilesY*tilesX];

This would create an array of the right size. To access the elements of the array,you just do this:

blah = tileArray[yindex+1*xindex+1];

That should work all the same... The +1 is there just to make sure you don''t try to use a zero. :D

I hope this helps.

Share this post


Link to post
Share on other sites
tryforfulluse:
hmmmm. Not really! :-)
Mind explaining a little further?



Edited by - PyroBoy on April 22, 2001 6:42:50 PM

Share this post


Link to post
Share on other sites
MrShaneParker:
Yep, that''s certainly a way around it... But that''s just using a 1-d array to BS a 2-d one. There MUST be a way to dynamicly allocate a 2D array...

Share this post


Link to post
Share on other sites
The 1D array method is better in most situations. For a dynamic 2D array you have to allocate an array of pointers, then use a for loop to allocate memory to each of those pointers.

"Finger to spiritual emptiness underlying everything." -- How a C manual referred to a "pointer to void." --Things People Said
Resist Windows XP''s Invasive Production Activation Technology!
http://druidgames.cjb.net/

Share this post


Link to post
Share on other sites
My book(C How to Program, 2nd edition) states:



An array can be created and assigned to int * chessBoardPtr as follows:

chessBoardPtr = new int[8][8];

This array can be deleted with the statement

delete [] chessBoardPtr;



I thought it may be an issue with the user-defined types, so I switched my code around to just allocate some ints, and I get the same errors. I really don''t envy the thought of writing an index equasion every time I access the array. I''d like to just write
tileArray[y][x] or something like that, and have it access the right spot on the array.

Share this post


Link to post
Share on other sites
So, just wrap in into a class, sort of like this:
    
template <class Type> class Array2D {
Type *Data;
Type **Begins;
public:

inline Type *operator [] (unsigned int a) {
return Begins[a];
}

Array2D(unsigned int px, unsigned int py) {
Data = new Type[px*py];
Begins = new Type *[py];
for(unsigned int a=0; a<py; a++) {
Begins[a] = &Data[px*a];
}
}
inline ~Array2D(void) {
delete [] Data;
delete [] Begins;
}
};

// Used like this:

Array2D <MyClass> MyArray(10,10);
MyClass ABC = MyArray[2][2];


Hopefully I didn't make any typos in there . You may want to add some error checking into that though.

"Finger to spiritual emptiness underlying everything." -- How a C manual referred to a "pointer to void." --Things People Said
Resist Windows XP's Invasive Production Activation Technology!
http://druidgames.cjb.net/

Edited by - Null and Void on April 22, 2001 7:20:22 PM

Share this post


Link to post
Share on other sites
Yes, of course wrapping it would alleviate the ease-of-use issue somewhat, but it still seems to be an overly elaborate "hack" solution to what really ought to be (and according to my book, ***IS***) an integrated part of the c++ language...
Not to knock your class, it''s very nice! :-)

I just can''t fathom how they could leave multidimentional array functionality out of the "new" keyword. Is it part of the ANSI C++ spec and MS just left it out of VC++? Or is my book completely wrong and it''s not a feature of c++ in the least?

Share this post


Link to post
Share on other sites
In vc++ you cant allocate a dynamic 2D array. I tried it but after reading vc++ documentation it clearly said that it is not posible. they suggest allocating a 1d array of pointers but that just looks like a mess to me.

go with a c++ class wrapper

Share this post


Link to post
Share on other sites
I''ve never seen a multidimension array new on any compiler I''ve ever used, not Borland, M$, nor DEC.
That doesn''t mean it''s not part of the spec though

You don''t have to wrap it in a class to use [][], but you do need a for loop every time you create or destroy a 2D array - unless you use the trick that null & void did. Then you can new & delete once, but you still need one for loop to setup the indexing array.

  
int i;
int* pInt;
int** IntArray2D;

IntArray2D = new (int*)[FirstDimension];
for(i=0; i<FirstDimension; i++)
IntArray2D[i] = new int[SecondDimension];

//this

pInt = IntArray2D[0];
i = pInt[1];
//is the same as this

i = IntArray2D[0][1];
//It''s not _really a 2D array of int''s in C/C++

//It''s an array of int*, which point to 1D int arrays...


for(i=0; i<FirstDimension; i++)
delete[] IntArray2D[i];
delete[] IntArray2D;


What Null&Void did is often preferable because the memory allocated will be one continuous chunk - like OpenGL or Dx matricies are.

...
What year was that book published?

Magmai Kai Holmlor
- The disgruntled & disillusioned

Share this post


Link to post
Share on other sites
hmmm. Sure would be a useful feature... Ah well. I guess i''ll have to set it up as a 1-d.

I think the book was originally published in 1992, but the copyright extends to 1994. I guess I''ll take whatever it says with a grain of salt from now on! :-)

Share this post


Link to post
Share on other sites
Here is exactly what you want:

  
struct TILE2D
{
BYTE type;
float minTU;
float minTV;
float maxTU;
float maxTV;
};

TILE2D **tileArray; //notice the **

int tilesX = 30;
int tilesY = 30;

tileArray = new TILE2D*[tilesY];
for (int i = 0; i < tilesY; i++)
tileArray[i] = new TILE2D[tilesX];



that will make the 2D array just like tileArray[tilesY][tilesX].

Possibility


Edited by - Possibility on April 22, 2001 8:26:32 PM

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Possibility is correct in the above post, but you still have to be careful. A lot of people would then try to to a memcpy( ) on this pseudo-2d array to copy data. Because the memory allocated isn''t continuous you''ll have all sorts of problems.

The 1-d method with index offsetting is the best approach in most cases. If you don''t want to abstract it, make an inline function or macro to emulate the [][] referencing.

Share this post


Link to post
Share on other sites