How to pass a matrix to a function

W

Wei-Chao Hsu

There is an error in my program. The error message is

e:\test\test\main.cpp(9): error C2664: 'fun' : cannot convert parameter 1
from 'int [2][3]' to 'int ** '

If I change the argument "int** a" to "int a[2][3], it will be OK. But, I
don't want to change the definition.
How can I pass the matrix to the function?

//-------------------------------------------------------------
void fun(int **a,const int row,const int col);

void main()
{

int a[2][3];
fun(a,2,3);
}

void fun(int **a,const int row,const int col)
{
for(int i=0;i<row;++i)
for(int j=0;j<col;++j)
a[j]=i*10+j;
}
 
F

Frane Roje

Try making your int **a into an int (*a)[3] this way you actualy tell the
computer you want a pointer to an array that has a 3 ints in it. If you had
an **int this is just double indirection, and with(*)[] you have a pointer
to an array.

HTH

--
Frane Roje

Have a nice day

Remove (d*el*ete) from email to reply
 
F

Frane Roje

Try making your int **a into an int (*a)[3] this way you actualy tell the
computer you want a pointer to an array that has a 3 ints in it. If you had
an **int this is just double indirection, and with(*)[] you have a pointer
to an array.

HTH

--
Frane Roje

Have a nice day

Remove (d*el*ete) from email to reply
 
N

Niels Dybdahl

e:\test\test\main.cpp(9): error C2664: 'fun' : cannot convert parameter 1
from 'int [2][3]' to 'int ** '

If I change the argument "int** a" to "int a[2][3], it will be OK. But, I
don't want to change the definition.
How can I pass the matrix to the function?

Usually int [2][3] is implemented as a flat array while int** is a pointer
to a pointer which is something completely different.
So it is not possible to transfer int a[2][3] as int**

Niels Dybdahl
 
R

Robert Bauck Hamar

There is an error in my program. The error message is

e:\test\test\main.cpp(9): error C2664: 'fun' : cannot convert parameter 1
from 'int [2][3]' to 'int ** '

That can't be done. int a[2][3] is not stored as an a**. It's stored
as an array, whith each element as an int[3]. You could define fun() like
this:

void fun(int a[][3], const int row)
{
for (...) for (...) a[j]=...;
}

Note all but the first index needs to be known at compile time. You
could also define fun() like this:

void fun(int *a, const int row, const int col)
{
for (int i=0;i<row;++i) for (int j=0;j<col;++j)
a[i*col + j] = i*10+j;
}

but then fun must be called as this:

fun(reinterpret_cast<int*>(a), 2, 3)

There is more than one way to do things, but: C++ has something called
classes. To implement a matrix is better done using this feature than
plain arrays.
If I change the argument "int** a" to "int a[2][3], it will be OK. But, I
don't want to change the definition.
How can I pass the matrix to the function?

You would need to change the definition of fun.
//-------------------------------------------------------------
void fun(int **a,const int row,const int col);

void main()

int main()
{

int a[2][3];
fun(a,2,3);
}

void fun(int **a,const int row,const int col)
{
for(int i=0;i<row;++i)
for(int j=0;j<col;++j)
a[j]=i*10+j;
}
 
W

Wei-Chao Hsu

I just learn C++ recently and need to rewrite some programs from FORTRAN to
C++. In the programs, the sizes of matrices are always determined at
runtime. Passing a multiple dimensional array to a function is very easy to
FORTRAN, but it seems to be a problem to C/C++.
 
W

Wei-Chao Hsu

I think I find the solution, but I don't know whether the method for
deallocating is correct. Any idea?
Another question- If I don't delete the memory, will it deallocate the
memory automatically after the function is ended?

//--------------------------------------------------------
void fun(int *a,const int row,const int col);

void main()
{
const row=9;
const col=8;
int a[row][col];
int *pa=&a[0][0];

fun(pa,row,col);
}

void fun(int *pa,const int row,const int col)
{
int **a=new int*[row];
a[0]=pa;
for(int i=1;i<row;++i)
a=&a[i-1][col];

for(int i=0;i<row;++i)
for(int j=0;j<col;++j)
a[j]=i*10+j;

delete [] a;
}
 
K

Karl Heinz Buchegger

Wei-Chao Hsu said:
I just learn C++ recently and need to rewrite some programs from FORTRAN to
C++. In the programs, the sizes of matrices are always determined at
runtime. Passing a multiple dimensional array to a function is very easy to
FORTRAN, but it seems to be a problem to C/C++.

Arrays in general are a pain in the ass in C++. Especially if they
need to be dynamically sized. A std::vector is much easier to
deal with since it is a first class object. An example
of using a std::vector has already been shown I think.
 
X

Xiaobin Yang

following code works.
void main()
{

int a[2][3]; use "int** a = NULL;"
fun(a,2,3);
}

void fun(int** & p_Array, const int row,const int col)
{
if (p_Array) delete p_Array;
p_Array = new int* [row];
for (int i = 0; i < row; i++)
p_Array = new int[col];

for(int i=0;i<row;++i)
{for(int j=0;j<col;++j)
{ p_Array[j]=i*10+j; }
}
}




-- xiaobin
 
X

Xiaobin Yang

Arrays in general are a pain in the ass in C++. Especially if they
need to be dynamically sized. A std::vector is much easier to
deal with since it is a first class object. An example
of using a std::vector has already been shown I think.

do you think following implementation is not worse than vector?

void fun(int** & a,const int row,const int col)
{
if (a) delete a;
a = new int* [row];
for (int i = 0; i < row; i++)
a = new int[col];

for(int i=0;i<row;++i)
{for(int j=0;j<col;++j)
{ a[j]=i*10+j; }
}
}
 
K

Karl Heinz Buchegger

Xiaobin said:
Arrays in general are a pain in the ass in C++. Especially if they
need to be dynamically sized. A std::vector is much easier to
deal with since it is a first class object. An example
of using a std::vector has already been shown I think.

do you think following implementation is not worse than vector?

void fun(int** & a,const int row,const int col)
{
if (a) delete a;
a = new int* [row];
for (int i = 0; i < row; i++)
a = new int[col];

for(int i=0;i<row;++i)
{for(int j=0;j<col;++j)
{ a[j]=i*10+j; }
}
}


Yes I think that the above is worse then using a std::vector.
But for reasons that cannot be seen in the code snippet.
The above code is correct in the allocation but the problem
is that the user of that code has to remember to
properly free the memory again or else he has a memory leak.
No such action is necessary if std::vector does the job. A
std::vector takes care of itself.
 
X

Xiaobin Yang

do you think following implementation is not worse than vector?
void fun(int** & a,const int row,const int col)
{
if (a) delete a;
a = new int* [row];
for (int i = 0; i < row; i++)
a = new int[col];

for(int i=0;i<row;++i)
{for(int j=0;j<col;++j)
{ a[j]=i*10+j; }
}
}


Yes I think that the above is worse then using a std::vector.
But for reasons that cannot be seen in the code snippet.
The above code is correct in the allocation but the problem
is that the user of that code has to remember to
properly free the memory again or else he has a memory leak.
No such action is necessary if std::vector does the job. A
std::vector takes care of itself.

How ?

If we don't write code like following, how can vector know when
it should freee memory?

================================
vector<long> c;
// memory is freed here.
c.~vector<long>(); // or "c.clear()";
===========================

if we don't call destructor or clear(), it will be there before it goes
out of scope. in this sense, vector is not 100% automatic in
memory-deallocation. if we have to call clear(), it's not better
than "delete [] p_Array". isn't it?

-- xiaobin
 
K

Karl Heinz Buchegger

Xiaobin said:
do you think following implementation is not worse than vector?

void fun(int** & a,const int row,const int col)
{
if (a) delete a;
a = new int* [row];
for (int i = 0; i < row; i++)
a = new int[col];

for(int i=0;i<row;++i)
{for(int j=0;j<col;++j)
{ a[j]=i*10+j; }
}
}


Yes I think that the above is worse then using a std::vector.
But for reasons that cannot be seen in the code snippet.
The above code is correct in the allocation but the problem
is that the user of that code has to remember to
properly free the memory again or else he has a memory leak.
No such action is necessary if std::vector does the job. A
std::vector takes care of itself.

How ?

If we don't write code like following, how can vector know when
it should freee memory?


Same as whith every other object in C++. std::vector frees
its memory when the object goes out of scope.
That's one of the reasons why we call a std::vector
a first class object. It handles all its internals by
itself. The user of std::vector doesn't need to worry about
it.

int main()
{
std::vector< int > MyVec;

MyVec.push_back( 5 );
MyVec.push_back( 7 );

}


There is no memory leak in the above. The std::vector
enlarges itself if needed and frees the memory when
the object is destroyed.
if we don't call destructor or clear(), it will be there before it goes
out of scope.
Yep.

in this sense, vector is not 100% automatic in
memory-deallocation. if we have to call clear(), it's not better
than "delete [] p_Array". isn't it?

Sure it is.
If you forget to delete [] p_Array, it stays in memory forever.
If you don't call clear() the vector will free everything when
it goes out of scope. Just put the vector into the scope where
you want to have that 'dynamic array' and the vector will work
fine without you having to do anything.

Other then in rare circumstances you *never* call a destructor
by yourself. It is done automatically when the object goes out of scope.
In fact this is one of the key points of object oriented programming:
objects handle their internals by themselfs.
 
W

Wei-Chao Hsu

Good idea! Thanks, Yang.
void main()
{

int a[2][3]; use "int** a = NULL;"
fun(a,2,3);
}

void fun(int** & p_Array, const int row,const int col)
{
if (p_Array) delete p_Array;
p_Array = new int* [row];
for (int i = 0; i < row; i++)
p_Array = new int[col];

for(int i=0;i<row;++i)
{for(int j=0;j<col;++j)
{ p_Array[j]=i*10+j; }
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,173
Latest member
GeraldReund
Top