0

I am trying to write a generic matrix Transpose function

void reverse(int** v , int vertexes )
{
    for(int i=0;i<vertexes;i++)
        for(int j=0;j<vertexes;j++) 
        {
            if(v[i][j] == 1 && v[j][i]==0){
                v[j][i] = -1;
                v[i][j] = 0;        
            }
        }

    for(int i=0;i<vertexes;i++)
        for(int j=0;j<vertexes;j++) 
        {
            if(v[i][j] == -1 )
                v[i][j] = 1;
        }
} 

And the main function being

void matrix_graph::process()
{

    int v[7][7] = {
        {0,1,0,0,0,0,0},
        {0,0,1,1,0,0,0},
        {1,0,0,0,0,0,0}, 
        {0,0,0,0,1,0,0},
        {0,0,0,0,0,1,0},
        {0,0,0,1,0,0,1},
        {0,0,0,0,0,1,0}
    };

    reverse(v,7);
}

And i as expected got a

error C2664: 'reverse' : cannot convert parameter 1 from 'int [7][7]' to 'int **'

Is there anything we can do about it?

Is the best we can do to access i, j of the passed 2-d array (passing v as a one dimensional array) is

v[vertexes*i][j]
keelar
  • 5,814
  • 7
  • 40
  • 79
sethi
  • 1,869
  • 2
  • 17
  • 27
  • possible duplicate of [elegant way to create&pass multi-dimensional array in c++?](http://stackoverflow.com/questions/4655149/elegant-way-to-createpass-multi-dimensional-array-in-c) – awesoon Jun 22 '13 at 17:16
  • possible duplicate of [Passing two-dimensional array via pointer](http://stackoverflow.com/questions/3515045/passing-two-dimensional-array-via-pointer) – AnT stands with Russia Jun 22 '13 at 17:20
  • Also http://stackoverflow.com/questions/8203700/conversion-of-2d-array-to-pointer-to-pointer – AnT stands with Russia Jun 22 '13 at 17:21
  • Why tag it C++ when you want a C solution? – bennofs Jun 22 '13 at 17:21
  • @bennofs, Don't care, already edited. – awesoon Jun 22 '13 at 17:22
  • 1
    Why do you want a C solution when the sample code is in C++? Or does C have member functions now? – kfsone Jun 22 '13 at 17:25
  • The compiler is right to complain. You need `void reverse(int* square, int size)`. Ie, you have a square matrix. The data is order with *row* and *column* stripping. You **don't** have an array of pointer to ints. That would be `int v[7] = { &v0, &v1...}` with `int v1[7]`, etc. – artless noise Jun 22 '13 at 17:50

5 Answers5

5

Just use

void reverse(int vertexes, int v[vertexes][vertexes])

Trying to use int ** will not immediately work with built-in 2D arrays. If you want to insist on int ** interface, then you'll have to create an additional temporary row-index array as described here

Passing two-dimensional array via pointer

or here

conversion of 2D array to pointer-to-pointer

Community
  • 1
  • 1
AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • Error 1 error C2057: expected constant expression in that line – sethi Jun 22 '13 at 17:26
  • @sethi: You are using an old C compiler. You need C99 compiler for this feature to work. If you have to use an old compiler, then you'll have to follow options presented at the links. There's no other way, if you want to use built-in arrays. – AnT stands with Russia Jun 22 '13 at 17:29
  • I get it..its a very clean solution – sethi Jun 22 '13 at 17:31
  • Andrey..i think your solution in the second link (http://stackoverflow.com/questions/8203700/conversion-of-2d-array-to-pointer-to-pointer ) is a good solution too...2 good things about that is array is still initialized easily and the solution is localized ... – sethi Jun 22 '13 at 18:01
3

You should be careful, as an array of array is not the same as a double pointer. While it's true that arrays decays to pointers, using a pointer to a pointer as an array of arrays means you're actually using it as an array of pointers.

Instead have the argument as a pointer to arrays, like

int (*v)[7]
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • I want to write a generic function..where user can pass any 2-d array with the dimension – sethi Jun 22 '13 at 17:21
0

I think using heap memory will solve the issue. So rather than declaring int[7][7] v, which goes in the stack, using malloc will create the array in the heap and allow you to manipulate it outside of the functions.

int** v = (int**)malloc((sizeof(int*) * 7));

for (int i = 0; i < 7; i++)
{
    v[i] = (int*)malloc(sizeof(int)*7);
}
// then initialize v here...
jh314
  • 27,144
  • 16
  • 62
  • 82
0

To get rid of the error and keep your idea, you can call your function as follows:

reverse(&v[0][0],7);

and modify the function and prototype:

void reverse(int* v , int vertexes ){
for (int i=0; i<vertexes; i++)
    for (int j=0; j<vertexes; j++){
    // do stuff 
    v[i*vertexes+j]; //equivalent of v[i][j]
    v[j*vertexes+i]; //equivalent of v[j][i]
}
Alexandru Barbarosie
  • 2,952
  • 3
  • 24
  • 46
0

I suppose a good design here would be to create a Matrix class that encapsulates the operations on a matrix. I would also suggest not to use pointer-to-pointer to store the data of the matrix, but to use a 1D array and index transformations, like:

int &Matrix::at( int i, int j )
{
    // check the constraints
    return m_array[i * m_width + j];
}

This simplifies the memory management and prevents dealing with bugs in handling unnecessary complex constructions.

A multidimensional array in C/C++ is not the same as a pointer-to-pointer-to-...-to-pointer. The multidimensional array in fact is a continuous memory area with index transformations done by a compiler, whereas the pointer-to-pointer is a 1D array of pointers pointing to other dimensions. In this case the memory might not be continuous and there are additional pointers in this scenario which are absent in case of the multidimensional array.

To summarise, in case of an array:

int array[7][7] = { ... };
array[2][3] ===
    &array[0][0] /* start of the array */ +
    2 * 7 + 3    /* index transformation 2D to 1D*/

In case of a pointer:

int **pointer;
pointer[2][3] === *(*(pointer + 2) + 3)

These two code fragments do two completely different things and you should not cast a multidimensional array to a many-stars-pointer and vice-versa.

Kane
  • 5,595
  • 1
  • 18
  • 27
  • I am sorry, there were no "pure C" requirement at the beginning and there was a C++ tag. For pure C some wrappers (`struct` and supporting function) around a matrix would be useful, because passing some random plain pointers is not the best idea. Array vs pointer part remains valid also for pure C. – Kane Jun 22 '13 at 17:57