0

How can I pass a two or multi dimensional array as a parameter of a function without defining its size??

Here is my example code:

 void test(int *a) { 
    a[0][0] = 100; 
 } 
 int main()  { 
    int a[2][2]; 
    test(a); 
    cout<<a[0][0]; 
 }

5 Answers 5

5

You can use a template for static sizes

template<int first, int second> void func(int(&array)[first][second]) {
}

Or a vector of vector for dynamic sizes

void func(std::vector<std::vector<int>> array) {
}

However, what you most definitely cannot do is use an int**. An int[] will decay to an int* but an int[][] will decay to an int*[]. Think about it- else, how would the language differentiate between an array of pointers, and a multi-dimensional array of values? You really should never use primitive arrays anyway, they're begging for trouble with no safety and implicit conversions up the wazoo. Grab a nice, safe std::array (or boost::array if you're in C++03) for static arrays, or std::vector for dynamic arrays.

Sign up to request clarification or add additional context in comments.

Comments

3

If you're working exclusively with statically-sized, stack-allocated arrays, then a function template will do exactly what you're asking for:

#include <cstddef>
#include <ostream>
#include <iostream>

template<std::size_t N, std::size_t M>
void func(int (&arr)[N][M])
{
    std::cout << "int[" << N << "][" << M << "]\n";
    for (std::size_t n = 0; n != N; ++n)
        for (std::size_t m = 0; m != M; ++m)
            std::cout << arr[n][m] << ' ';
    std::cout << '\n' << std::endl;
}

int main()
{
    int i1[2][3] = { { 4, 5, 6 }, { 7, 8, 9 } };
    int i2[4][2] = { { 1, 3 }, { 5, 7 }, { 9, 11 }, { 13, 15 } };
    func(i1);
    func(i2);
}

Comments

0

Passing the pointer to the array. For example, if you have a bidimensional int array you'll need to pass int** p, along with the dimensions of the array.

3 Comments

void test(int **p, int r, int c) { std::cout<<p[0][1]<<std::endl; } int main() { int **p = (int**) malloc(2*sizeof(int*)); for(int i =0;i<2;i++) p[i] = (int*)malloc(2*sizeof(int)); p[0][1]=3; test(p,2,2); } ps. remember to release it when you have done
No, this is definitely wrong. An int[] will decay to an int* but an int[][] will NOT decay to an int**.
What do you mean? Nobody here talked about int[][], just of a "multi dimensional array", and a int** IS a bidimensional array.
0

For built-in arrays, you have to specify the size of all dimensions but the last dimension or indexing won't work.

If your goal is just to have a function that takes multi-dimensional arrays of any size, I'd consider boost::multi_array_ref (or boost::const_multi_array_ref)

Update: Since passing by pointer appears to be the answer that's getting the most attention (although I think the multi_array_ref is good... unless boost isn't available or something) then here's an example that flattens the array and doesn't limit you by array dimensions (although you still need size information to make it useful)

void f(int* array /* should probably pass in the size here - in this case, 4 */)
{
   array[3] = 9;
}

int main()
{
   int array[2][2] = { {1,2}, {3,4} };

   // Note: The array is flattened here. If you truly need to remember the multi-dimensional nature, you need to pass in enough information to specify all the dimensions... maybe something like a vector<size_t> (that's what the multi_array_ref uses). I guess if you have a limited number of dimensions then a couple size_t will work for you

   test(&array[0][0]);

   std::cout << array[1][1] << std::endl;
   return 0;
}

2 Comments

The question says without defining size, which can be done when passing the array (and can be worked around, sort of, other times). In addition, Boost is best used only when needed, like any additional library. Throwing it around like the end-all-be-all of libs just kills your build time.
I interpreted it as without defining the size that the function accepts. I.e. f(int i[2][]) only works for a subset of 2-dimensional arrays. I don't consider boost the end-all-be-all, but if you want to safely pass a multi dimensional array then you need the pointer and some description of its shape. That's what a boost::multi_array_ref is. If you want to reinvent it, so be it.
-3
int a[][]

Can be passed as:

function name(int **arr) {
    //your code, you can then access it just like you would have accesses your array:
       arr[3][2]
}

4 Comments

int main() { int a[2][2]; name(a); cout<<a[0][0]; } It gives error error: argument of type "int (*)[2]" is incompatible with parameter of type "int **"
try void test(int a[][2]) as your function prototype. Please ensure that your last dimensions value should be in the prototype declaration.
But I dont want to specify the dimension of the array.. In some cases I would like to pass different size arrays to this function..
The function test() signature should look like: void test(int **arr, int row, int col); And the calling function should call it like test(my_array, 2, 3), where my_array is defined as int *my_array[2] with each element pointing to a 3 dimensional array. So you can do a for loop to setup my_array: for(i=0; i<2; i++) my_array[i]=&x[i], where 2D array x is defined as x[2][3].

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.