Sign in to follow this  
MorDuc

struct with a pointer to an array

Recommended Posts

Hey All. think this is my first post on the forum. I'm trying to make a tetris clone. pointers is not my strong side. tried looking in some tuts. but cant grasp this one by myself. i have struct with a pointer int *pBlock; its planned to be pointing at a 3D array. pBlock = &iBlock[0][0][0]; but i'm having some trouble using the array through the pointer. can someone show me how. thanks in advance. Regards Morten Due

Share this post


Link to post
Share on other sites
You probably tried to use the pointer like this:
pBlock[0][1][2] = 1;
This is not valid in C++. A pointer to an integer can operate as a 1D array, but that's it. There is in fact no simple syntax to have a pointer to a 3D array just different levels of difficulty in trying to go around the language limitations. One solution would be to have a struct for each block and then you would have a pointer to the Block, something like this:
struct TetrisBlock
{
int Block[4][4][4];
};

TetrisBlock iBlock;
// code
TetrisBlock * pBlock = &iBlock;
pBlock->Block[0][1][2] = 1;
Other solutions are to use a 1D array to simulate a 3D array with integer arithmetic:
int iBlock[4*4*4];
int x = 0;
int y = 1;
int z = 2;
int *pBlock = iBlock;
pBlock[x+(4*y)+(4*4*z)] = 1;
You could also try to use std::vector< std::vector< std::vector<int> > >, but that's probably not necessary. Or you could being to utilize boost, in particular multi-array which has facilities to help do what you want, but it might be overkill for you.

Hope some of this helps.

edit: oh I left out pointer to a 4x4 2D array. That's probably my least favorite solution though. I think it would look like this:
int * pBlock[4][4];
Yes, the two dimensions need to be hardcoded. int * pBlock1[4][4]; and int * pBlock2[4][3]; declare two variables of different types.

Share this post


Link to post
Share on other sites
if you need two (or more) dimensional array, you need to define pointer to pointers

int **arr;
//int arr[m][n]
arr = (int**)malloc(sizeof(int*)*m);
for(i=0; i<m; i++){
arr[i] = (int*)malloc(sizeof(int)*n);
}

and this generates a m*n integer array for you. first it creates a m sized int pointer array, after for each element of this array, it creates a n sized integer array

Share this post


Link to post
Share on other sites
Quote:
Original post by shultays
if you need two (or more) dimensional array, you need to define pointer to pointers

If you know all but the first dimensions at compile-time, you can create multidimensional arrays dynamically without pointers to pointers:

void do_something(int number_of_lines)
{
typedef int row[10]; /* <--- note compile-time constant */
row *board = malloc(number_of_lines * sizeof(row)); /* <--- note variable */

board[0][0] = 42;

/* ... */

free(board);
}

Share this post


Link to post
Share on other sites
Quote:
Original post by shultays
if you need two (or more) dimensional array, you need to define pointer to pointers

int **arr;
//int arr[m][n]
arr = (int**)malloc(sizeof(int*)*m);
for(i=0; i<m; i++){
arr[i] = (int*)malloc(sizeof(int)*n);
}

and this generates a m*n integer array for you. first it creates a m sized int pointer array, after for each element of this array, it creates a n sized integer array


No, this is a bad way to do things (and is not actually making an "m*n integer array"). It incurs extra overhead, and implies things about the storage that are not true (namely, that it would make sense to vary the "row sizes" individually.

A proper rectangular array is a single storage block. Because the size in each dimension is known, there is no need to hold a separate allocation for each "row"; internally, a little arithmetic is done to translate indices into a single index.

In C and C++, multi-dimensional arrays sized at compile time (e.g. int x[4][4]) do this automatically. Otherwise, It Depends(TM). In C++, it is often appropriate to use std::vector, boost::multi_array, or boost::array - sometimes more than one of those, in varying configurations. In C, you normally have to roll it yourself, but blindly choosing the "dynamically allocate each row" solution is sloppy coding.

But to answer the OP's question, it is, actually, possible, with a pointer-to-array type. I recommend the use of typedefs to ensure getting them right.


#include <stdio.h>

int main() {
int test[7][4][4];
typedef int subarray[4][4];
subarray* test_ptr = test; /* the pointer-to-array type. */
int i, j, k, counter = 0, *verifier;
for (i = 0; i < 7; ++i) {
for (j = 0; j < 4; ++j) {
for (k = 0; k < 4; ++k) {
test_ptr[i][j][k] = counter++;
}
}
}
for (verifier = &(test[0][0][0]), i = 0; i < 7 * 4 * 4; ++verifier, ++i) {
printf("%d\n", *verifier);
}
}

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