Skip to main content
gamedev.net
🔒 Locked

Pointer to a pointer pointer

Started by Ciphersoftware 11 replies 650+ views
Original Post
Ciphersoftware
Ciphersoftware
Hello, I''m trying get rid of all my global variables and ive encountered this problem: -------------------------------------------- I have a multidimensional array for my gameboard: gameboard[10][20]; I want to pass a pointer to this multi-dimensional array to a function. What I would like to know is, how do I successfully create a pointer to my multidimensional array? This works, kinda: int gameboard[10][20]; int *p=(int *)gameboard; But the problem with the above example is that the pointer only points to the data in the first row. So the logical thing to do would be to create a double pointer **. This is where I get scared: int gameboard[10][20]; int **p=(int **)gameboard[10][20]; The problem with the above example is that when I dereference **p I get an error because I''m dereferencing a pointer with an invalid address (0x00000000). Do I have to allocate memory for my pointer-to-pointer-pointer? I dont know what the heck to do. Please help.
Ciphersoftware website Support the open source community
Shannon Barber
Shannon Barber
No, it's a pointer-pointer-pointer

      
int*** pGameBoard;
int GameBoard[10][20];
pGameBoard = &GameBoard

//That's actually a GameBoard pointer

// which may or may not be what you really want.


for(int i=0; i<10; i++)
for(int j=0; j<20; j++)
{
int x = (*pGameBoard)[i][j];

//or

int y = pGameBoard[0][i][j];
//that works but is somewhat miss-leading

}

//if you you want an alias for a GameBoard, you can do this:

int** GameBoardAlias;
GameBoardAlias = &GameBoard[0];



Edited by - Magmai Kai Holmlor on October 13, 2001 11:41:51 PM
The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
Dactylos
Dactylos
Umm... no, that won''t work. (int[10][20]) and (int**) aren''t compatible types, they have different memory layout. (int[10][20]) is stored sequentially in memory, while (int**) is an array of pointers to arrays of int (so to speak).

either declare your function like this:
  
void some_function(int gameboard[10][20])
{
// do something to the gameboard

}

Or make your gameboard a dynamically allocated 2D array (int**). Or if you make it 1D, then it won''t matter if it''s statically or dynamically allocated.
EbonySeraph
EbonySeraph
Think of it this way. Your board is ten rows right? Or just ten pointers to a row. Since a row is a collection of sequential data(array) its also a pointer. The address of gameboard[x] is the address of the start of a row(of ints). gameboard[x][y] goes to the address of x, and from there an offset of y*the size of int. &gameboard[x][y] is just a pointer to a single integer value.

To simplify all the crap that I just said, just use (int **) as the data type for your parameter. Of course passing by reference is a good way to ease any complications. If you do that you can just use the gameboard in another function just as you would use it in the function that called it. If you''re not going to change the board pass with it with the const keyword.

"Ogun''s Laughter Is No Joke!!!" - Ogun Kills On The Right, A Nigerian Poem.
"Ogun's Laughter Is No Joke!!!" - Ogun Kills On The Right, A Nigerian Poem.
Dactylos
Dactylos
quote:
Original post by EbonySeraph
Think of it this way. Your board is ten rows right? Or just ten pointers to a row. Since a row is a collection of sequential data(array) its also a pointer. The address of gameboard[x] is the address of the start of a row(of ints). gameboard[x][y] goes to the address of x, and from there an offset of y*the size of int. &gameboard[x][y] is just a pointer to a single integer value.

To simplify all the crap that I just said, just use (int **) as the data type for your parameter. Of course passing by reference is a good way to ease any complications. If you do that you can just use the gameboard in another function just as you would use it in the function that called it. If you're not going to change the board pass with it with the const keyword.

"Ogun's Laughter Is No Joke!!!" - Ogun Kills On The Right, A Nigerian Poem.

The problem is that if you declare gameboard as:

int gameboard[10][20];

then gameboard won't be a pointer to ten pointers to 20 ints. gameboard will be a pointer to 200 ints (all stored sequentially in memory). At the same time gameboard *is* those 200 ints, i.e.

gameboard == &gameboard

is true!

To make things simple declare your gameboard like this:
    
int **gameboard;

// allocated the gameboard with:

gameboard = int*[10];
for (int i = 0; i < 10; ++i)
gameboard[i] = new int[20];

// deallocated the gameboard with:

for (int i=0; i < 10; ++i)
delete[] gameboard[i];
delete[] gameboard;

(Of course you shouldn't use magic numbers like that, store your X and Y sizes in a const int or something)

Edited by - Dactylos on October 13, 2001 12:29:23 AM
Corillian
Corillian
a multidimensional array is actually a different way of referring to a normal array. A normal array could be represented like this:

      

char ar[] = "Hello";



This is a pointer to char (a string) holding 5 characters.
A multidimensional array (2 levels deep) is actually a pointer an array of x pointers which each hold y characters.

  
x y
char ar[4][4];

ar[0][0] = 'A';
ar[0][1] = 'B';

char *p = (char*)ar;

cout << p[0] << p[1] << endl;



If you have an array that is 3 levels deep then it is a pointer to an array of x pointers which each point to an array of y pointers which each hold z characters. (isn't that confusing hehe)

  
x y z
char ar[3][3][3];

ar[0][0][0] = 'A';
ar[0][0][1] = 'B';
ar[0][0][2] = 'C';
ar[0][1][0] = 'D';
ar[0][1][1] = 'E';
ar[0][1][2] = 'F';
ar[1][0][0] = 'G';
ar[1][1][0] = 'H';
ar[1][1][1] = 'I';

char *p = (char*)ar;

cout << p[0] << p[1] << p[2] << endl;
cout << p[3] << p[4] << p[5] << endl;
cout << p[9] << p[12] << p[13] << endl;



In the above example lets assume that the first (left to right) subscript is x, the second y, and the third z. Using the above example we can construct our equation as the following:

x y z
char ar[3][3][3];

ar[0][0][0] = 'A';
ar[0][0][1] = 'B';
ar[0][0][2] = 'C';
ar[0][1][0] = 'D';
ar[0][1][1] = 'E';
ar[0][1][2] = 'F';
ar[1][0][0] = 'G';
ar[1][1][0] = 'H';
ar[1][1][1] = 'I';

char *p = (char*)ar;

x = 3;
y = 3;
z = 3;

We are searching for the position of element [2][1][0].

xp = 2;
yp = 1;
zp = 0;

   

int a = (z-(z-zp))+((y-(y-yp))*z)+((x-(x-xp))*y*z);
cout << p[a] << endl;
cout << a << endl;



(z(z-zp)) finds the position of it in the z subscript (in this case that is 0-2)

((y-(y-yp))*z) finds the position of it in the y subscript and then multiplies it by the # of z each y element contains which is added to the position of z.

((x-(x-xp))*y*z) finds the position of it in the x subscript and then multiplies it by the # of y each element has and the # of z each element of y has. It then adds it to the total of z + the total of y to come up with your final position in the array.


I hope this helps you out and didn't make it any more confusing than it was before=D. I never said I was good at explaining things =). It is kind of confusing but it's easy once you get the hang of it.

Edited by - Corillian on October 14, 2001 1:28:53 AM
Corillian
Corillian
oh yeah, btw, to answer your original question =D

  

void MyFunc(char *pAr)
{
//do stuff

}

int main()
{
char ar[5][4][3][2];

MyFunc((char*)ar);

return 0;
}

Dactylos
Dactylos
Corillian: You're contradicting yourself. The kinds of arrays you are declaring are *not* pointers to arrays of pointers to...

In fact your whole example depends on your multidimensional arrays *not* being pointers to arrays of pointers to elements.

Edited by - Dactylos on October 14, 2001 1:40:49 AM
Corillian
Corillian
Oops, you are correct. Sry, it''s 2:00 in the morning . It''s how I visualize it in my head though. It makes more sense to me, though I spose it isn''t correct. I would change it just that I think I need 2 go 2 sleep now
Shannon Barber
Shannon Barber
quote:

a multidimensional array is actually a different way of referring to a normal array.


Only when the array is of constant size! That''s the problem with the code I posted, it only works for a dynamically initialized 2D array.
The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
davidko
davidko
hehe,

I think everyone was so wrapped up trying to get that pointer-to-pointer thing, they forgot what the original question was! Yeah, just do it like anonymous poster says, except you don''t really need the 10 there, but i suppose it makes things clearer.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.