Mike N.
Mike N.

Reputation: 358

How do I pass multi-dimensional arrays of unknown size into a function using pointers in c++?

Like the question says, I am trying to pass multi-dimensional arrays into a function to print it to a file for an engineering project. The format for which the data is inputted CANNOT be changed, so please don't suggest I just input it as a different datatype.

This particular function anticipates a two-dimensional array (although I have others with three dimensions after this one), where nothing is known about the size of the array until run-time. I know I must use pointers to point to each row of the array separately, but I have NO idea what the syntax is for passing it to the function. In the following code, the array in question is 'block'. The main function is just a little testing example I made to try to make it work:

#include<fstream>
using namespace std;

void of_write_blocks(string filename, string block_type[], int **block,
            int grid[][3], string grade_type[], int grade[][3], int n_blocks, int m[])
{
    ofstream file_out(filename.c_str(),ios::app);
    file_out<<"\nblocks\n(\n";

    for(int i=0;i<n_blocks;++i) {
            file_out<<"   "<<block_type[i]<<" ( ";
                    for(int j=0;j<m[i];++j)
                            file_out<<block[i][j]<<" ";
            file_out<<") ( ";
            file_out<<grid[i][0]<<' '<<grid[i][1]<<' '<<grid[i][2]<<" ) ";
            file_out<<grade_type[i]<<" ( ";
            file_out<<grade[i][0]<<' '<<grade[i][1]<<' '<<grade[i][2]<<" )\n";
    }
    file_out<<");\n";
}


//testing example:
int main()
{       
    int block[6][9];
    for(int i=0; i<6;++i) 
            for(int j=0; i<9;++j)
                    block[i][j] = i*j;

    int grid[6][3];
    for(int i=0; i<6;++i)
            for(int j=0; i<3;++j)
                    block[i][j] = i*j;


    int grade[6][3];
    for(int i=0; i<6;++i) 
            for(int j=0; i<3;++j)
                    block[i][j] = i*j;

    string grade_type[6] = {"simpleGrading"};
    string block_type[6] = {"hex"};
    int m[6] = {8};
    int n_blocks = 6;

    of_write_blocks("name",block_type,block,grid,grade_type,grade,n_blocks,m);
}       

any help is appreciated!

Upvotes: 1

Views: 2129

Answers (4)

iammilind
iammilind

Reputation: 69988

Why can't use a reference of array. See below example:

char c[10];
int i[10][20];
double d[10][20][30];

Write a wrapper function like this:

template<typename T, int SIZE>
void Array (T (&a)[SIZE])
{}
template<typename T, int SIZE1, int SIZE2>
void Array (T (&a)[SIZE1][SIZE2])
{}
template<typename T, int SIZE1, int SIZE2, int SIZE3>
void Array (T (&a)[SIZE1][SIZE2][SIZE3])
{}

This is just an example to demonstrate the syntax which will elegantly receive the array without any copying and also avoids confusing pointers. Also, if you are aware that you are going to use only for int then simply remove the typename and explicitly mention int. i.e.

template<int SIZE>
void Array (int (&a)[SIZE]); // explicitly mention int

Upvotes: 0

Arlen
Arlen

Reputation: 6835

For clarity I removed all the irrelevant code from your example.

#include <iostream>
#include <fstream>

using namespace std;

void of_write_blocks(int **block, int bh, int bw){

  for(int i = 0; i < bh; ++i)
    for(int j = 0; j < bw; ++j)
      cout << block[i][j] << " ";
  cout << endl;
}

int main(){       

  int bh, bw;
  cin >> bh >> bw;

  int** block;
  block = new int*[bh];
  for(int k = 0; k < bh; k++)
    block[k] = new int[bw];

  // initialize the array
  for(int i = 0; i < bh; i++)
    for(int j = 0; j < bw; j++)
      block[i][j] = (i*bw) + j;

  of_write_blocks( block, bh, bw);
}       

In the main we are creating a 2D array and initializing it. Then we pass it to of_write_block, which prints the array. Is that what you wanted to do?

Upvotes: 0

Billy ONeal
Billy ONeal

Reputation: 106530

You can't. Multidimensional arrays are syntactic sugar, and are compiled directly into the code that does manipulations on the array, which is a single memory block. The dimensions are not passed into the function as parameters or anything like that as part of the array, as things are done in e.g. Java or C#.

If you need the dimensions of the array in your function, you'll need to just accept a pointer to the first element of the array, and the dimensions, and do the multiplies and adds to get the right index yourself.

Alternately, use something like a std::vector<std::vector<block>>, which pass the dimensions as part of the object, rather than a built in array.

Upvotes: 5

yasouser
yasouser

Reputation: 5177

If you have Boost installed, check out Boost Multi-Array.

Upvotes: 2

Related Questions