Archived

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

Dynamic Allocation Of 2D Arrays

This topic is 6083 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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
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