0

Suppose you have a two-dimensional array which has been initialized like

int M[5][5] = { {1,3,4,2,5},
                {3,5,1,6,2},
                {7,5,6,2,0},
                {6,2,9,7,6},
                {1,0,8,5,2} };

This M will be passed as a parameter to a function. However the function only accepts int** as parameter, not int [][5].

My question is, how to do this conversion?

C. Wang
  • 2,516
  • 5
  • 29
  • 46
  • @GrijeshChauhan please read the question again. Your comment does not relate to it. – Ivaylo Strandjev Feb 14 '14 at 15:44
  • @GrijeshChauhan That won't work; `p` could not be passed as an `int**`, it would be an `int***`. – TypeIA Feb 14 '14 at 15:44
  • 1
    @mbratch: why should it accept it? a bidimensional matrix is not an array of pointers, and by no it is directly convertible to it. – Matteo Italia Feb 14 '14 at 15:44
  • 1
    possible duplicate of [Cannot convert double \[\] \[\] to double \*\*](http://stackoverflow.com/questions/21731524/cannot-convert-double-to-double) `int **` and `int [][]` are very different things. See my [answer here](http://stackoverflow.com/a/21731756/1072468). – Nicu Stiurca Feb 14 '14 at 15:45
  • M declared like this is an array, not a pointer. if M were allocated with mallocs, then it would work. with gcc : error: cannot convert 'int (*)[5]' to 'int**' for argument '1' to 'void f(int**)' – johan d Feb 14 '14 at 15:46
  • @IvayloStrandjev hmm.. deleted... – Grijesh Chauhan Feb 14 '14 at 15:46
  • @MatteoItalia agreed. – lurker Feb 14 '14 at 15:49

2 Answers2

3

An array of pointers to pointers and a bidimensional array are completely different data structures in C:

  • int ** normally refers to an array of pointers, each of which points to a different row (allocated elsewhere)
  • int [5][5] under the hood is a plain linear array where the rows are stored one after each other, and the compiler automatically performs the calculations on the index to access the right element.

So, having an int[5][5], you have to build the array of pointers by yourself, which will act as an "index" for the rows of your matrix.

int * m2[5];
for(int i=0; i<5; ++i)
    m2[i]=M[i];
f(m2);
Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
0
template<unsigned...>struct indexes {};
template<unsigned Max, unsigned...Is>struct make_indexes:make_indexes<Max-1,Max-1,Is...>{};
template<unsigned...Is>struct make_indexes<0,Is...>:indexes<Is...>{};

template< class T, std::size_t X, std::size_t Y, unsigned...Is >
std::array<T*, X> as_jagged_helper( T(&arr)[X][Y], indexes<Is...> ) {
  return {arr[Is]...};
}

template< class T, std::size_t X, std::size_t Y, unsigned...Is >
std::array<T*, X> as_jagged( T(&arr)[X][Y] ) {
  return as_jagged_helper(arr, make_indexes<X>());
}

then simply call f(&(as_jagged(M)[0]));

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524