Pointer to array

Hi,

How can I make a pointer to the following table:

const int test[2][2] = { {1,2}, {3,4} }

Like this?
const int ** ptr = test;


Thanks!
G00fyAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

boycyCommented:
Yes, correct. Remember that test *is* a pointer to the table (an array identifier is the address of the first element, i.e. (test == &test[0][0]) is true).

--Rob
jweston1Commented:
const int test[2][2] = { {1,2}, {3,4} };
const int **ptr = (const int **)&test;
AxterCommented:
You use typedef to make a type, and then you can easily create a pointer for it.

Example code:

typedef int INT2X2[2][2];

const INT2X2 test = { {1,2}, {3,4} };


int main( int argc, char * argv[] )
{
      const INT2X2* ptr = &test;

      cout << (*ptr)[0][0] << endl;
      cout << (*ptr)[0][1] << endl;
      cout << (*ptr)[1][0] << endl;
      cout << (*ptr)[1][1] << endl;

      system("pause");
      return 0;
}

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Introduction to Web Design

Develop a strong foundation and understanding of web design by learning HTML, CSS, and additional tools to help you develop your own website.

rstaveleyCommented:
David (Axter) is of course right.

Note also that a reference if often syntactically nicer to use than a pointer...

      const INT2X2& ref = test;
      cout << ref[0][0] << endl;
      cout << ref[0][1] << endl;
      cout << ref[1][0] << endl;
      cout << ref[1][1] << endl;

jweston1's C-style cast was wrong:

      const int** ptr2 = (const int**)&test;

The need to cast should have raised alarm bells. It would still have been wrong but more more honest to use C++ casting, which would make you use the quite rightly much more alarming reinterpret_cast<>, which says I-know-better-than-the-compiler-this-type-really-is-a...

The int** type is a pointer to an array of integer pointers, typically used for a pointer to an array of pointers to arrays of int. You'd use this pointer for the following:

      int** ptr2 = new int*[2];
      ptr2[0] = new int[2];
      ptr2[0][0] = 1;
      ptr2[0][1] = 2;
      ptr2[1] = new int[2];
      ptr2[1][0] = 3;
      ptr2[1][1] = 4;
      cout << ptr2[0][0] << endl;
      cout << ptr2[0][1] << endl;
      cout << ptr2[1][0] << endl;
      cout << ptr2[1][1] << endl;
      delete[] ptr2[1];
      delete[] ptr2[1];
      delete[] ptr2;
G00fyAuthor Commented:
Axter solution works like a charm. But rstaveley, yours give this errors:
---
error C2440: 'initializing' : cannot convert from 'const int (*)[2]' to 'const int (&)[2][2]'
Reason: cannot convert from 'const int (*)[2]' to 'const int [2][2]'
There are no conversions to array types, although there are conversions to references or pointers to arrays
---
rstaveleyCommented:
Tested with gcc 3.2 and VC 7.1:

--------8<--------
#include <iostream>
using std::cout;using std::endl;

typedef int INT2X2[2][2];

const INT2X2 test = { {1,2}, {3,4} };

int main( int argc, char * argv[] )
{
      const INT2X2* ptr = &test;
      cout << (*ptr)[0][0] << endl;
      cout << (*ptr)[0][1] << endl;
      cout << (*ptr)[1][0] << endl;
      cout << (*ptr)[1][1] << endl;

      const INT2X2& ref = test;
      cout << ref[0][0] << endl;
      cout << ref[0][1] << endl;
      cout << ref[1][0] << endl;
      cout << ref[1][1] << endl;

      int** ptr2 = new int*[2];
      ptr2[0] = new int[2];
      ptr2[0][0] = 1;
      ptr2[0][1] = 2;
      ptr2[1] = new int[2];
      ptr2[1][0] = 3;
      ptr2[1][1] = 4;
      cout << ptr2[0][0] << endl;
      cout << ptr2[0][1] << endl;
      cout << ptr2[1][0] << endl;
      cout << ptr2[1][1] << endl;
      delete[] ptr2[1];
      delete[] ptr2[1];
      delete[] ptr2;

      return 0;
}
--------8<--------

Can you give me your error message from that G00fy?
G00fyAuthor Commented:
This compiles like a charm in both DevCPP and Visual C++.

But what I am trying to do is this:

------
#include <iostream>
#include <time.h>
using std::cout;using std::endl;

typedef int INT2X2[2][2];

const INT2X2 test = { {1,2}, {3,4} };
const INT2X2 test2 = { {1,2}, {3,4} };

int main( int argc, char * argv[] )
{
     srand(time(NULL));
     bool bChooseIt = rand()%2 ? true : false;

     const INT2X2& ref = bChooseIt ? test : test2;
     cout << ref[0][0] << endl;

     return 0;
}
--------

And this gives me the errors... Assignment works like a charm, but this give these errors:
D:\tmp\tmp\main.cpp(21) : error C2440: 'initializing' : cannot convert from 'const int (*)[2]' to 'const int (&)[2][2]'
        Reason: cannot convert from 'const int (*)[2]' to 'const int [2][2]'
        There are no conversions to array types, although there are conversions to references or pointers to arrays
G00fyAuthor Commented:
Works like a charm in MingW though, but how can I circumvent that problem? Via pointers yes, but otherwise?

Ok, found the solution myself, VisualC == stupid:

const INT2X2& ref = *(bChooseIt ? &test : &test2);

thanks all!
rstaveleyCommented:
Yes that wouldn't have worked because the construct needs a temporary object, which would mean reassigning the reference, which you can't do.

There are ways around this.

e.g.
--------8<--------
#include <iostream>
#include <time.h>
using std::cout;using std::endl;

typedef int INT2X2[2][2];

const INT2X2 test = { {1,2}, {3,4} };
const INT2X2 test2 = { {5,6}, {7,8} };

template<typename T>
inline T& chooser(T& true_opt,T& false_opt,bool choice)
{
      if (choice)
            return true_opt;
      else
            return false_opt;
}

int main( int argc, char * argv[] )
{
     srand(time(0));
     bool bChooseIt = rand()%2 ? true : false;

     const INT2X2& ref = chooser(test,test2,bChooseIt);
     cout << ref[0][0] << endl;

     return 0;
}
--------8<--------

Interestingly enough T1 (the technical report - which is going-to-be-not-quite-standard) has a wrapper for references to handle some of this clumsiness.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.