Vikas Sardana
Vikas Sardana

Reputation: 1643

error while passing a 2d array through pointer in c

There is an error while compiling the following program,can anyone tell me why the compiler giving such error?

`#include <stdio.h>
void display(int **,int,int);
int main ()
{
int a[3][4]={1,2,3,4,5,6,7,8,9,0,1,6};
display(a,3,4);


return 0;
}
void display(int **a,int b,int c){

}

Error while compiling

 ` ptr.c: In function ‘main’:

  ptr.c:6:1: warning: passing argument 1 of ‘display’ from incompatible pointer type [enabled by default]
  ptr.c:2:6: note: expected ‘int **’ but argument is of type ‘int (*)[4]’ `

Upvotes: 2

Views: 698

Answers (3)

Sarfaraz Nawaz
Sarfaraz Nawaz

Reputation: 361762

The first argument a to display() is of type int[3][4] which cannot convert into int**, because, as your compiler says, they're compatible types.

However, int[3][4] can convert into int(*)[4]. So you change the first parameter of display from int**a to int (*a)[4], then it will work fine.

Pedantically speaking, there is nothing like double-dimensional array in C (and C++) — a which is of type int[3][4] is actually an array of arrays, so it can convert into pointer to the first element of array — the type of the first element is int[4], so the pointer to the first element becomes int(*)[4]. Just like an array of type int[100] can convert into the int* (which is the pointer to the first element).

Upvotes: 1

Jerry Coffin
Jerry Coffin

Reputation: 490653

Although a 1D array can convert to a pointer (and will at the drop of a hat), a 2D array won't convert to a pointer to pointer.

The problem is that inside the function the compiler needs to know (at least) the width of the array to compute the memory address based on the 2D coordinates you give it. Therefore, you need to specify at least the one dimension explicitly. More generally, given an N-dimensional array, you need to specify all the coordinates but the first.

Since you're using C++, it's almost certainly better and cleaner to use a small wrapper around a std::vector that stores the array width internally, so you can pass it around and operate on it easily.

template <class T>
class matrix { 
    size_t columns_;
    std::vector<T> data;
public:
    matrix(size_t columns, size_t rows) : columns_(columns), data(columns*rows) {}

    T &operator()(size_t column, size_t row) { return data[row*columns_+column]; }
};

Upvotes: 3

Adam Rosenfield
Adam Rosenfield

Reputation: 400642

An array is not a pointer. An array decays into a pointer to its first element in certain contexts, but only at the first level -- an array of arrays decays into a pointer to arrays, but not to a pointer to pointers. The rule is not applied recursively.

See the C FAQ for a more detailed explanation.

Upvotes: 2

Related Questions