Solved

# Create an array of pointers to two dimensional arrays

Posted on 2004-04-27
2,008 Views
At first glance this seemed as though it should be easy but I'm having a tough time figuring out how to make this happen.  So basically what I need to know is the syntax for declaring an array of pointers to 2D arrays of integers and how to make the pointers point to my two dimensional arrays of integers. Thanks in advance for any help.
0
Question by:swingler
• 9
• 7
• 6
• +3

LVL 12

Expert Comment

Hi swingler,
Use vectors. For readability, you can use a typedef chain:

typedef vector< vector < payload > > TwoDimArr;
typedef vector<2Darr*> NestedArr;

...and there you are.

Cheers,
Stefan
0

LVL 30

Expert Comment

Example:
int Array[3][5]={{1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15}};
int (*Arrayp)[5] = &Array[0];

for(int x= 0;x < 3;++x)
{
for(int y= 0;y < 5;++y)
cout << Arrayp[x][y] << ", ";
}
0

LVL 17

Expert Comment

If you must use horrible pointers and horrible arrays, in the following we have an array of 2D arrays and the imaginatelyly named p points to the first of these....

--------8<--------
#include <iostream>

int main()
{
typedef int int_100_x_100[100][100];
int_100_x_100* p = new int_100_x_100[10];

int value = 0;
for (int i = 0;i < 10;i++)
for (int x = 0;x < 100;x++)
for (int y = 0;y < 100;y++)
p[i][x][y] = ++value;

{
int i,x,y;
std::cout << "Choose an array 0..9: ";std::cin >> i;
std::cout << "Choose an x-coord 0..99: ";std::cin >> x;
std::cout << "Choose a y-coord 0..99: ";std::cin >> y;
if (i >= 0 && i < 10 && x >= 0 && x < 100 && y >= 0 && y < 100)
std::cout << "Value is: " << p[i][x][y] << '\n';
}

delete []p;
}
--------8<--------
0

Author Comment

I'm going to sweeten the pot, as it seems there is a better solution than my idea of an array of pointers to 2D arrays

stefan73-
If I were to use your typedef chain how would that effect the way in which I would access the data. Sample code would be appreciated

rstaveley-
I have to agree that the use of pointers and arrays isn't my ideal situation. Would you suggest a solution similar to stefan73's proposed solution?
0

LVL 30

Expert Comment

swingler,

No comment on the code I posted, which does answer your original question?
0

LVL 30

Assisted Solution

Axter earned 75 total points
The following class is an easy to use method that allows you to create a dynamic 2D array.

template < class T>
class dynamic_2d_array
{
public:
dynamic_2d_array(int row, int col):m_row(row),m_col(col), m_data((row!=0&&col!=0)?new T[row*col]:NULL){}
~dynamic_2d_array(){if(m_data) delete []m_data;}
inline T* operator[](int i) {return (m_data + (m_col*i));}
inline T const*const operator[](int i) const {return (m_data + (m_col*i));}
private:
const int m_row;
const int m_col;
T* m_data;
};

Using above class, you can declare a 2D array via following syntax:
dynamic_2d_array<int> MyArray(3, 4);

You can still get a pointer to this array via following:
int *PtrToArray = &MyArray[0][0];

And you can access this array just like a C-Style array.
MyArray[0][0] = 3;
cout << MyArray[0][0] << endl;
0

LVL 3

Expert Comment

>> I have to agree that the use of pointers and arrays isn't my ideal situation. Would you suggest a solution similar to stefan73's proposed solution?

what would be the situation which you think you have to use an array of pointers to two dimensional arrays? that would better qualify what 'solution' should be used.
0

LVL 17

Accepted Solution

rstaveley earned 75 total points
> Would you suggest a solution similar to stefan73's proposed solution?

Yes. My example doesn't make it look too pretty, but if std::vector was used instead of arrays, it would like like this:
--------8<--------
#include <iostream>
#include <vector>

typedef std::vector<int> IntV;
typedef std::vector<IntV> IntVV; // 2D "array" of ints
typedef std::vector<IntVV> IntVVV; // "Array" of 2D "array" of ints

int main()
{
IntVVV intVVV(10);
int value = 0;
for (int i = 0;i < 10;i++) {
IntVV& intVV = intVVV[i];
intVV.resize(100);
for (int x = 0;x < 100;x++) {
IntV& intV = intVV[x];
intV.resize(100);
for (int y = 0;y < 100;y++)
intV[y] = ++value;
}
}

{
int i,x,y;
std::cout << "Choose an array 0..9: ";std::cin >> i;
std::cout << "Choose an x-coord 0..99: ";std::cin >> x;
std::cout << "Choose a y-coord 0..99: ";std::cin >> y;
if (i >= 0 && i < 10 && x >= 0 && x < 100 && y >= 0 && y < 100)
std::cout << "Value is: " << intVVV[i][x][y] << '\n';
}
}
--------8<--------
0

Author Comment

Axter-
I appologize if you are feeling left out. Your solution does indeed answer my original question; however, after reading your solution and stefan73's solution I realized pointers to arrays was probably not the simplest solution for me to implement. My grasp of pointers has always been tenuous at best, and if I can avoid using them I'm all for it. I think I was getting in over my head with an array of pointers to 2D arrays. :)

CoolBreeze-
I have three sparse matrices that I need to be able to compare and manipulate(add & remove items) and pass to functions.

0

LVL 30

Expert Comment

>> I have three sparse matrices that I need to be able to compare and manipulate(add & remove items) and pass to functions.

Can you give us the declartions for these functions?
0

Author Comment

Axter-
Sorry, I can't. They haven't been written yet.
0

LVL 30

Expert Comment

>>Sorry, I can't. They haven't been written yet.

Then maybe you can give us a better idea of what you're trying to do, or what is your end goal.

0

Author Comment

My end goal is to create 2 2D matrices and add points to it and then to compare the 2D matrices and store the points that match in a third 2D matrix and to output that third matrix.
0

LVL 3

Expert Comment

from my understanding, the size of a matrix is unlikely to change (maybe I'm wrong). Even if it changes, usually you don't assign it back to the same matrix (am I right?).

so I would suggest just a linear 1D array. First element stores the number of columns, second element stores the number of rows. The rest of the elements of the array stores the actual data. And if your matrices' size is going to be large, you can apply run-length encoding here, simple and fast (less fast than without the encoding).

assuming without encoding, comparing two matrices is just comparing the third element to the last element of the two arrays. Storing the points is just copying the elements that are equal to a third array.

by adding/removing items, do you actually mean changing an element in the matrix? I can't imagine a 2x2 matrix with one more element added in.

I don't see the reason of using pointers here, maybe I am missing something.
0

LVL 30

Expert Comment

>>My end goal is to create 2 2D matrices and add points to it and then to compare the 2D matrices and store the points that match in a third 2D matrix and to output that third matrix.

Easy example:

void SomeFunc(int (*Array1)[5], int (*Array2)[5], int (*Array3)[5])
{
for(int x= 0;x < 3;++x)
{
for(int y= 0;y < 5;++y)
Array3[x][y] = Array1[x][y] + Array2[x][y];
}
}

int main(int , char*)
{
int Array1[3][5]={{1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15}};
int Array2[3][5]={{1,1,1,1,1},{1,1,1,1,11},{11,11,11,11,11}};
int Array3[3][5];

SomeFunc(&Array1[0], &Array2[0], &Array3[0]);

0

Author Comment

Thanks for the input everyone!
0

Author Comment

rstavely-
Your sample code causes a seg fault on the resize statement.

intVV.resize(100);

Any ideas why that might be?
0

LVL 17

Expert Comment

Works fine for me on GNU 3.2 and VC 7.1, and it looks like standard stuff. What's your environment?
0

LVL 17

Expert Comment

It shouldn't be necessary, but what happens if you replace...

intVV.resize(100);

...with....

intVV.reserve(100); // Reserve the elements first (shouldn't be necessary!)
intVV.resize(100); // Now resize the array, using the reserved elements

If it still crashes, does it bomb out on the reserve or resize?
0

LVL 17

Expert Comment

Try:

IntVVV intVVV(10);
std::cout :: "Size is " << intVVV.size() << '\n';

...just to confirm that the IntVVV array is initially correctly sized as 10.

If you've got a manky STL implementation, you could try...

IntVVV intVVV;
//intVVV.reserve(10);   // <- Try this too, if it still plays up
intVVV.resize(10);

...to resize the array explicitly... but it really oughtn't to be necessary.

Please let me know what you find. I'm curious.
0

Author Comment

Doh!

Sorry rstaveley, your code works great. Chalk that up to user error. I created an instance of IntVVV but didn't specify any size, like so:

IntVVV intVVV;

Once I initialized the IntVVV with a size everything fell into place.

0

LVL 17

Expert Comment

No worries, swingler, glad that it wasn't the Universe falling down around me as it is apt to do from time to time ;-)
0

Expert Comment

//I hope the following code will solve the problem
//here I tried to create a 2X3 matrix with a single dimension array created dynamically
int row=2,col=3 //these values can be accepted dynamically
int val=1,i=0,j=0;

//create and insert into 2D array
/*matrix will look like following
1     2    3
4     5    6
*/

int *matrix=NULL;
matrix= new int[row*col];
for (i=0;      i<row;      i++)
for(j=0;      j<col;      j++, val++)
{
cout<<((2*i)+(i+j))<<endl;
m[(2*i)+(i+j)] = val;
}

//Display 2D array
for (i=0;      i<row;      i++)
{
for(j=0;      j<col;      j++)
cout<<m[(2*i)+(i+j)]<<"      ";
cout<<endl;
}

delete [] m; //releasing the memery allocated
0

Expert Comment

there were some errors in my previous comment.
I'm really sorry for misleading you guys..

//here I tried to create a 2X3 matrix with a single dimension array created dynamically

int row=2,col=3; //these values can be accepted dynamically

//create and insert into 2D array
int val=1,i=0,j=0;

int *matrix=NULL;
matrix= new int[row*col];
for (i=0;      i<row;      i++)
for(j=0;      j<col;      j++, val++)
{
cout<<((2*i)+(i+j))<<endl;
matrix[(2*i)+(i+j)] = val;
}

//Display 2D matrix
for (i=0;      i<row;      i++)
{
for(j=0;      j<col;      j++)
cout<<matrix[(2*i)+(i+j)]<<"      ";
cout<<endl;
}

delete [] matrix;   //Release the memory allocated
0

LVL 17

Expert Comment

What are those hard-coded 2s doing in there?

Perhaps this helps...
--------8<--------
#include <iostream>
#include <iomanip>

int main()
{
int rows = 2,columns = 3;

int *matrix = new int[rows*columns];

int value = 1;
for (int row = 0;row < rows;++row)
for (int column = 0;column < columns;++column)
matrix[row*columns+column] = value++;

for (int row = 0;row < rows;++row) {
for (int column = 0;column < columns;++column)
std::cout << std::setw(4) << matrix[row*columns+column];
std::cout << '\n';
}

delete []matrix;
}
--------8<--------
0

LVL 17

Expert Comment

Your mistake was that you were making your row size governed by the number of rows rather than the number of columns. Using more explicit variable names makes it more obvious.
0

Expert Comment

Yea..you are correct..
0

Expert Comment

Hi rstaveley
I'm really sorry to tell u that that piece of code will not work rather we can go for my code...
did u test that code before posting it..

suppose when u insert items...
the second row will overwrite the contents of the first row..i think i'm correct just chekc it out
shibi
0

LVL 17

Expert Comment

Just checked it (compiled with VC 7.1) and got this output:

1   2   3
4   5   6

Looks OK to me.

With VC 6, you need to put a scope round the for loops to prevent it from brumbling about reusing the variable name and return 0, because it predates the standard.

i.e.
--------8<--------
#include <iostream>
#include <iomanip>

int main()
{
int rows = 2,columns = 3;

int *matrix = new int[rows*columns];

int value = 1;
{
for (int row = 0;row < rows;++row)
for (int column = 0;column < columns;++column)
matrix[row*columns+column] = value++;
}

{
for (int row = 0;row < rows;++row) {
for (int column = 0;column < columns;++column)
std::cout << std::setw(4) << matrix[row*columns+column];
std::cout << '\n';
}
}

delete []matrix;
return 0;
}
--------8<--------

If you are using GNU 3.2+, you should be OK.

Are you getting a logic error or a compilation error?

The second row doesn't overwrite the first because the row variable offsets the index by the required number of columns.

matrix[row*columns+column] = value++;
^^^
0

## Featured Post

### Suggested Solutions

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their waâ€¦
In days of old, returning something by value from a function in C++ was necessarily avoided because it would, invariably, involve one or even two copies of the object being created and potentially costly calls to a copy-constructor and destructor. Aâ€¦
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.