tags:

views:

177

answers:

2

Hi stackers!

What is the right way to create a pointer to pointer object? Like for example,

int **foo;
foo = new int[4][4];

Then the compiler gives me an error saying "cannot convert from int (*)[4] to int **.

Thanks.

+10  A: 
int **foo = new int*[4];
for (int i = 0; i < 4; i++)
   foo[i] = new int[4];

Clarification:

In many languages the code above is called a jagged array and it's only useful when the "rows" have different sizes. C++ has no direct language support for dynamically allocated rectangular arrays, but it's easy to write it yourself:

int *foo = new int[width * height];
foo[y * height + x] = value;
Filip Navara
weird, the code first above gives me an error saying missiong ;..
sasayins
Try it now. I've removed the parentheses from the first "new" statement around the type. This compiles with GCC 4.3, at least.
Filip Navara
great! thanks alot. it worked.
sasayins
*"C++ has no direct language support for rectangular arrays"* is simply wrong. Writing `int foo[4][4]` gives you a rectangular array. Dynamic multi-dimensional arrays are tricky, to be sure, and are addressed in multiple questions on StackOverflow.
dmckee
I should have written dynamic rectangular arrays, you are right.
Filip Navara
http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.16 ... for anyone interested in multi-dimensional arrays in C++.
Filip Navara
I think you mean “*jagged* array”, not “jugged.”
Konrad Rudolph
@Konrad Right, thanks for spotting it, fixed.
Filip Navara
+8  A: 

Using raw new is a bit unwieldy to use. The inner dimension (last 4) must be a compile time constant, in addition. You also have to remember to delete the array once you are finished using it.

int (*foo)[4] = new int[4][4];
foo[2][3] = ...;
delete[] foo;

If that feels too "syntactic braindead", you can use typedef to prettify it

typedef int inner_array[4];
inner_array *foo = new int[4][4];
foo[2][3] = ...;
delete[] foo;

That's called a rectangular 2-dimensional array, because all the rows (4 of them, which can be determined at runtime) have the same width (which must be known at compile time).

Alternatively, use std::vector, with which you don't need to mess around with delete anymore, and which will also handle the raw pointer mess:

std::vector<int> v(4 * 4);
v[index] = ...;

You may later add or remove integers from the vector as you wish. You could also create a vector< vector<int> >, but i find it unwieldy to use, because you have to manage the separate row-vectors (which can be of varying lengths), and they are not seen as "one unit" together.

You can always create a function that maps a two dimensional coordinate to a one-dimensional index

inline int two_dim(int x, int y) {
  return y * 4 + x;
}

v[two_dim(2, 3)] = ...;

For a simple two-dimensional array whose size you know beforehand, you don't need new at all, though

int x[4][4]; 
x[2][3] = ...;
Johannes Schaub - litb
thanks alot for the tips/pointers.
sasayins
you're welcome :)
Johannes Schaub - litb