Hello,

I am a newbie and trying to pass a 2 - dimensional array to a function in C++ from main(). Then, once inside that subroutine, I want to change the contents of this 2D array and be able to access the changed elements of this 2D array later in the main().

Waiting for a response. :)

You can not pass a array to a function without the element number of each dimension. in the function, it will not know the number of the elements.
1. you can use struct to pass multidimensional array. for example:

struct aaa
{
int value[10][20];
}


int function (struct aaa& parameter)
{
for(int i=0; i<10; i++)
{
for (int j=0; i<20; j++)
{
parameter[j] = i*j;
}
}
}
  1. tell the function the number of each dimension's element.

    void function(int& aaa[][], int 1d, int 2d)
    {
    for(int i=0; i<1d; i++)
    {
    for(int j=0; j<2d; j++)
    {
    aaa[j] = i*j;
    }
    }
    }

  2. use vector instead of array; I think this is the best way if don't care the performance.

2) tell the function the number of each dimension's element.

void function(int& aaa[][], int 1d, int 2d)

you dont need to say int& aaa just int aaa will be enough, also i think that you will have to give the 2nd subscript of the array int aaa[][col]

another method is to pass pointer to array

function(int (*p)[col],int row,int col)
{
      int* q = *p;
      for(int i=0;i<row;i++)
      {
          for(int j=0;j<col;j++)
          {
              cout << *q << endl;
              q++;
          }
      }
}

since 'p' is a pointer to an array, when we increment it, it points to the next memory address of its type, means the next array. Thus we used another pointer to be able to access each element. Just another way of writing the function.

> you dont need to say 'int& aaa' just 'int aaa' will be enough, also i think that you will have to give the 2nd subscript of the array 'int aaa[][col]'

---Yes, you are right. It's necessary to give the length of all dimensions except the first dimension.


another method is to pass pointer to array

since 'p' is a pointer to an array, when we increment it, it points to the next memory address of its type, means the next array. Thus we used another pointer to be able to access each element. Just another way of writing the function.

------maybe, the following code can demonstrate what you said a little better.

void function(int p[][10],int row,int col)
{
int* q = *p;
for(int i=0;i<row;i++)
{
for(int j=0;j<col;j++)
{
cout << *q << " ";
q++;
}
cout<<endl;
}
}

a

void function(int& aaa[][], int 1d, int 2d)
{
for(int i=0; i<1d; i++)
{
for(int j=0; j<2d; j++)
{
aaa[j] = i*j;
}
}
}

This is wrong, for many reasons. First, this is an array of arrays of references. The caller is not going to be able to pass a multidimensional array of ints in to that. Second, you cannot have "[][]" in the parameter list; all but the last dimension must have a constant dimension in it (the last [] gets converted to a pointer).

I don't think you're allowed to call a variable '1d' or '2d'...

You can pass the 2-D array as a int *, pointing to the first element. You have to calculate the location of the elements in the array in your function, e.g.:

void function(int *aaa, int r, int c){
   for(int i=0; i<r; i++){
      for(int j=0; j<c; j++){
         aaa[i*c+j] = i*j;
         }
      }
   }

calling the function is accomplished by:

int a[6][6];
   
   // pass a pointer to the first element
   function(&a[0][0], 6, 6);

   // or alternately use a cast
   function((int*)a, 6, 6);

   // or alternately use array row dereferencing
   function(a[0], 6, 6);

   // or alternately use dereferencing (I find this a bit weird that *a == a && a == &a)
   function(*a, 6, 6);

Cut and paste works, as a bootstrap to get you going.

If you have int array[2][3][4]; and you want to pass that to a function, then you simply do

void myFunc ( int array[2][3][4] );  // prototype
void myFunc ( int array[2][3][4] ) {  // definition
    array[0][0][0] = 0;
}

And calling it is similarly easy with myFunc( array ); Great so far, not a * to be seen.

Now it turns out that the left-most dimension is unnecessary (some tools will complain if you leave the size there, others will just ignore it). So you could write either of these as well without changing any of the functionality.

void myFunc ( int array[][3][4] ); // empty left-most dimension
void myFunc ( int (*array)[3][4] ); // using pointer notation, if you like extra edit

Yes, the () are needed in this case.

Likewise, the parameter name can be changed as well, just as with any other formal / actual parameter name of a function.

Another consequence of the left-most dimension being ignored is that you can use the same function for ANY array which differs only in the left-most dimension (think about why there is only one strcpy function for any length of string).
So

int small[2][3][4];
int large[200][3][4];
myFunc( small );
myFunc( large );

Ah, but now you say how do I know how many of the left-most dimension to use?
Well an example would be say strncpy() or fgets(), which pass the size.

Refined, we get
Cut and paste works, as a bootstrap to get you going.

If you have int array[2][3][4]; and you want to pass that to a function, then you simply do

void myFunc ( int array[2][3][4], size_t size );  // prototype
void myFunc ( int array[2][3][4], size_t size ) {  // definition
    array[0][0][0] = 0;
}

int small[2][3][4];
int large[200][3][4];
myFunc( small, 2 );
myFunc( large, 200 );

If you are not newbie enough to know pointers, then this is for you:

You can pass the address of the very first element of the array like this

main()
void func(int *aptr,int m,int n);

{ 
  int a[5][5]; // assuming array is 2D of 5x5 size
  int *aptr;
  :
  :
  aptr=&a[0][0];
 func(aptr,5,5);
 :
 :
}

void func(int *aptr,int m,int n)
{
 /*To access the value of array elements use this for a[i][j]:
*(aptr+ n*i+j)
for e.g to display you would have to do this 

for(int i=0;i<m;i++)
 for(int j=0;j<n;j++)
  cout<<" "<<*(aptr+ n*i + j);
*/
 :
 : // process as required
}

However I would be glad if someone could give some alternative to this formula of accessing a[j], as it might prove to be a problem in 3D arrays or more.

Till then, Mr., Use this.

There is nothing new in the code you have posted (see posts above). Re your concern about scalability of calculating the pointer offset (or array index): it will work for any array dimension size (but it may become hard to read, in which case it should be wrapped up in an inline function or macro).

Even though I'm pretty sure this thread is dead, here's a new way (for this thread anyways) to access the array from a function (array is 3D in this case):

// x is a pointer to the first element of the array
// np is number of planes in array
// nr is number of rows in array
// nc is number of columns in array
int dispArray(int *x, int np, int nr, int nc){
   int (*ptr)[nr][nc] = (int (*)[nr][nc])x;
   
   for(int i = 0; i < np; i++){
      for(int j = 0; j < nr; j++){
         for(int k = 0; k < nc; k++){
            cout << dec << ptr[i][j][k] << endl;
            }
         }
      }      
   }
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.