struct with a pointer to an array

Started by
4 comments, last by Zahlman 14 years, 7 months ago
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
Advertisement
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;// codeTetrisBlock * pBlock = &iBlockpBlock->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.

C++: A Dialog | C++0x Features: Part1 (lambdas, auto, static_assert) , Part 2 (rvalue references) , Part 3 (decltype) | Write Games | Fix Your Timestep!

thanks for the help, the struct option you mentioned first, should be all i need.
so think im going for that one.
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 = (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
taytay
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);}
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 = (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[j][k] = counter++;			}		}	}	for (verifier = &(test[0][0][0]), i = 0; i < 7 * 4 * 4; ++verifier, ++i) {		printf("%d\n", *verifier);	}}

This topic is closed to new replies.

Advertisement