Array of Pointers to Objects

Started by
19 comments, last by snk_kid 18 years, 10 months ago
Hi All, I know this has been covered 100 times, but I still couldn't find a solution to my problem. I have a dynamic array of pointers to Tile objects declared as... Tile **pTiles; I allocate the array using malloc, like... pTiles=(Tile **)malloc(nTilesAcross*nTilesDown*sizeof(Tile *)); and then initialize each tile using... for (int y=0; y < nTilesDown; y++) for (int x=0; x < nTilesAcross; x++) pTiles[x,y]=new Tile(nTileSize, x*nTileSize, y*nTileSize); Which seems to work fine. When I come to release however, I have problems. My release code looks like... // release tiles for (int y=0; y < nTilesDown; y++) for (int x=0; x < nTilesAcross; x++) { if (pTiles[x,y] != NULL) delete pTiles[x,y]; } // delete pointer array free(pTiles); It deletes the first tile at [0,0] fine, but when it trys to delete the second tile [1,0] I get an error because the destructor for the tile object is somehow pointing to the first tile [0,0] which has already been destroyed. What is going on here? Also, as I side issue why can I not declare the array of pointers using... pTiles=new (Tile *)[nTilesAcross, nTilesDown]; and then free it using... delete [] pTiles; Thanks all
Advertisement
I think pTiles[x,y] should be pTiles[x][y] or pTiles[y*nTilesAcross+x] depending on how you want to do it.
Let me be the first to say: Use std::vector or std::list. Ok.. now that's done.


OK, the problem with your code is, you can't index arrays like that. The reason is simple - the "," operator is "evaluate these two operands and return the second one.

So: "0,1" return 1, while "1,0" returns 0. "12,pie" returns pie.
This means that foo[0,1] will become foo[1].

So, index your arrays as foo[1][0] and so on.


Next, you can't actually alocate it like that - what you have there is a pointer to a pointer (**), you need to then alocate an array of pointers (for your columns), and then for each of those pointers, you then alocate your array of objects.

It would look something like:
// init your array of pointersint** foo = new (int*)[10];// for each pointer in the array, initialize an array of objectsfor(size_t i = 0; i < 10; i++){    foo = new int[10];}// then access your objects as so:foo[0][0] = 1234;dostuff(foo[2][8]);// delete in reverse of how you created:for(size_t i = 0; i < 10; i++){    delete[] foo;}delete[] foo;


And, of course, you should be able to fill in how to use maloc and free in place of new and delete (I recomend you use new and delete if you're in C++ - and I recomend you use C++ [smile]).



The alternative is to alocate the whole thing at once, and access parts of it manually:

// constants for width and heightconst size_t W = 10, H = 10;// The entire map:int* foo = new int[W*H];// Accessing your map, at location (w,y) (or you could use x,y or whatever)int GetAtLocation(size_t w, size_t h){    return foo[w+h*W];}


This method is probably more efficient. It uses less memory, and can probably be indexed much faster.
Quote:Original post by doho
I think pTiles[x,y] should be pTiles[x][y] or pTiles[y*nTilesAcross+x] depending on how you want to do it.


You are right... I am coming from C#! However, now...

pTiles=(Tile **)malloc(nTilesAcross*nTilesDown*sizeof(Tile *));
for (int y=0; y < nTilesDown; y++)
for (int x=0; x < nTilesAcross; x++)
pTiles[y*nTilesAcross+x]=new Tile(nTileSize, x*nTileSize, y*nTileSize);

works, but...

pTiles=(Tile **)malloc(nTilesAcross*nTilesDown*sizeof(Tile *));
for (int y=0; y < nTilesDown; y++)
for (int x=0; x < nTilesAcross; x++)
pTiles[x][y]=new Tile(nTileSize, x*nTileSize, y*nTileSize);

Does not!? I get a compile error saying...

f:\My Documents\Visual Studio Projects\test2\terrain.cpp(20): error C2679: binary '=' : no operator found which takes a right-hand operand of type 'Tile *' (or there is no acceptable conversion)

Can I not have two-dimensional arrays of pointers?

Thanks
Quote:Original post by Raeldor
Can I not have two-dimensional arrays of pointers?

No.

You can have a one dimentional array of pointers each with its own one dimentional array of pointers (which requires a two-stage alocation process - see my code). It will look just like a 2D array of pointers when you address it.

But yeah - the manual addressing method will probably be faster.
Of course, that is not the problem with your code (whoops). The error you are getting is because you are trying to assign a "Tile*" to a "Tile". Make your map type Tile*** and then you should be ok.
Quote:Original post by Andrew Russell
Quote:Original post by Raeldor
Can I not have two-dimensional arrays of pointers?

No.

You can have a one dimentional array of pointers each with its own one dimentional array of pointers (which requires a two-stage alocation process - see my code). It will look just like a 2D array of pointers when you address it.

But yeah - the manual addressing method will probably be faster.


Thanks, I almost having it working now. Only thing that is not compiling at the moment is...

pTiles=new (Tile*)[nTilesAcross*nTilesDown];

I get the error...

f:\My Documents\Visual Studio Projects\test2\terrain.cpp(18): error C2143: syntax error : missing ';' before '['

just to be picky its not good practice to mix delete, free, new , malloc.

And Shouldn't it be delete[] ?

and try
pTiles=new ((Tile*)[nTilesAcross*nTilesDown]);
Quote:Original post by anonuser
just to be picky its not good practice to mix delete, free, new , malloc.

And Shouldn't it be delete[] ?

and try
pTiles=new ((Tile*)[nTilesAcross*nTilesDown]);


I am trying to use just new and delete. I tried with the brackets and still got the error...

f:\My Documents\Visual Studio Projects\test2\terrain.cpp(18): error C2059: syntax error : '['

My new code reads...

pTiles=new ((Tile*)[nTilesAcross*nTilesDown]);
You're going for this right?
pTiles[] ?
well you need to know sizes of port parts of the array.

pTiles=new Tile[nTilesAcross*nTilesDown];

will an array of Tiles that big.
assuming pTiles is defined as follows:
Tile **pTiles = new Tile[10][nTileAcross*nTilesDown];

will give you 10 arrays of arrays.

Get my drift?

when using new to generate an array that big, you do not do it like you would malloc.

new Type[size of array];

note this notaion is also used for pointers that are not arrays (won't discuss this further).

This topic is closed to new replies.

Advertisement