Sign in to follow this  
Waffler

pointer confusion

Recommended Posts

I'm trying to do something which involves quite a confusing usage of pointers, and I would like to know of a way in with I can be assured it is set up correctly -- for instance, some sort of programming tricks to keep track of it all. Essentially, it is set up similar to this:
class A
{
public:
  A *neighbor[9];  // pointers to neighboring cells in 2D array
};

A *a;   // dynamically created array of A objects
A **b;  // pointer to array of pointers pointer to elements in a (set as a 2D grid)

/*
  GRAPHICAL EXAMPLE:
      +-+-+-+-+-+-+--+--+
  a = |0|1|2|3|4|5|..|24|
      +-+-+-+-+-+-+--+--+

      +--+--+--+--+--+
  b = |0 |1 |2 |3 |4 |  <- Each points to an element in a
      +--+--+--+--+--+
      |5 |6 |7 |8 |9 |
      +--+--+--+--+--+
      |10|11|12|13|14|
      +--+--+--+--+--+
      |15|16|17|18|19|
      +--+--+--+--+--+
      |20|21|22|23|24|
      +--+--+--+--+--+

                    +--+--+--+
  a[12]->neighbor = |6 |7 |8 |  <- Each points to a cell in b,
                    +--+--+--+     with a[12]->neighbor[4]
                    |11|12|13|     pointing pointing to it's
                    +--+--+--+     own cell
                    |16|17|18|
                    +--+--+--+

  I want to swap pointers through a[i]->neighbor to change which
  of a b[j] is pointing to, so each object a only needs to be
  concerned with what is withing it's own local proximity.
*/
As you can see, with pointers pointing to pointers and indrectly changing which pointer is pointing where, there is bound to be confusion in writing the code. I'm afraid there will be pointers pointing towards the wrong locations, and such an event may be a nightmare to debug. What would be a good way of eleminating this possibility of confusion. I'm more asking for a design theory or some good tips for thinking about working with pointers in complex ways.

Share this post


Link to post
Share on other sites
Basically, you just want a nice dynamically-allocated 2D array, yes? Well, not too much trouble then:


MapTile** the_map; // this is our 2D map of "MapTiles"

// build the map
// create the columns first - this creates an array of new MapTile pointer-pointers
the_map = new MapTile *[num_columns];
// foreach column, create each row
for (int counter = 0; counter < num_columns; counter++) {
// this creates an array of new MapTiles pointers too
the_map[counter] = new MapTile [num_rows];
}

// okay, map is built! now just use like this
the_map[column][row];

//Now of course you'll need to erase the memory when you are done with it.
// foreach column, delete the row (array of pointers):
for (int counter = 0; counter < num_cols; counter++) {
delete[] the_map[counter];
}
// now delete all the columns (array of pointer-pointers):
delete[] the_map;




Anyway, basically this approach lets you have an array[][] syntax, which is quite convenient. However, a safer way to do this without all the fuss is a vector of vectors:

std::vector< std::vector<Thing> > v;

That lets you access Things with the same syntax of v[][]

EDIT: -------------------------

Now if was you i would STOP THERE and encapsulate the whole "map" into a class with an easy interface like:

Map.GetObjectAt( x, y );

^^^ This is what makes things simpler, not some fancy pointer syntax. Let the map worry about pointers and pointer-pointers. Objects on the map should have no such worries.

Then let objects deal with location in a more intuitive, human sort of way. All they really need to know is where they are, say x=10, y=5. So if you need to know where "object A"s neighbors are, now it just has to spit out some coordinates:

Map.GetObjectAt( my_x, my_y + 1); // to the north
Map.GetObjectAt( my_x, my_y - 1); // to the south
Map.GetObjectAt( my_x + 1, my_y); // to the east
Map.GetObjectAt( my_x - 1, my_y); // to the west

Share this post


Link to post
Share on other sites
Thank you ... but that doesn't seem to fully apply to what I meaning to ask. I was more asking for some object oriented design theory...

I thought about it for a little while, and decided to use inline functions with descriptive names to do what I wanted.

Ex:

b[i]->get_brick()->get_neighbor_cell(CENTER); // points back around to b[i]
b[i]->get_brick()->get_neighbor_brick(RIGHT); // points to the right of b[i]->get_brick(), which is b[i+1]->get_brick().




This should eliminate any mental confusion I may have been experiencing.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this