Reputation: 67
I am trying to make functions(adding, subtracting, product, etc) taking as arguments dynamic 2-d arrays.
For example, given two 2-d double arrays with each one having 2 rows and 2 columns:
double** m1;
m1 = new double *[2];
for (int i = 0; i < 2; ++i) {
m1[i] = new double[2];
}
double k1 = 1.0;
for (int i = 0; i < 2; ++i) {
for (int j = 0; j < 2; ++j) {
m1[i][j] = k1;
k1 += 2.0;
}
}
double** m2;
m2 = new double *[2];
for (int i = 0; i < 2; ++i) {
m2[i] = new double [2];
}
double k2 = 2.0;
for (int i = 0; i < 2; ++i) {
for (int j = 0; j < 2; ++j) {
m2[i][j] = k2;
k2 += 2.0;
}
}
And I made an adding function for them. It first checks whether the two arrays have the same numbers of rows and columns. But as the arrays are totally dynamic(both numbers of rows and columns) and were declared as pointers to pointers, I can't get the numbers of rows and columns.
For example, The value of
sizeof(m1[0])
is 4, that is, the bite size of double pointer (probably) but, the value of
sizeof(m1[0][0])
is 8 which is the right size of double type.
I want the adequate version of the former.
double** add_m(double **m1_, double** m2_) {
//HERE first part that needs the numbers of arguments' rows and columns.
if ((sizeof(*m1_) != sizeof(*m2_)) || (sizeof(**m1_) != sizeof(**m2_))) {
cout << "The sizes of the matrices don't match each other";
return 0;
}
else {
//HERE second part that needs the numbers of arguments' rows and columns.
int num_rows = sizeof(m1_[0])/sizeof(m1[0][0]);//??
int num_cols = sizeof(m1_[0][0])/sizeof(m1_[0][0]);//??
double** res;
res = new double*[num_rows];
for (int i = 0; i < num_rows; ++i) {
res[i] = new double[num_cols];
}
for (int i = 0; i < num_rows; ++i) {
for (int j = 0; j < num_cols; ++j) {
res[i][j] = m1_[i][j] + m2_[i][j];
}
}
return res;
}
}
EDIT: Most of answers say using already existing tools like vector, matrix. Then only for curiosity, no way of doing it? The only way is making vector-like class or matrix-like class from scratch?
Upvotes: 1
Views: 1787
Reputation: 438
Size of() operator in C/C++ will give you the size of the data type passed in. So in your example when you say sizeoff(m1_) you will get the size of double pointer but not the size of memory behind it. As far as I know there is no clean way of doing what you want to do.
A better way of doing this as @Scheff suggested in comments is having a wrapper class for your matrix and storing your matrix in a std::vector (either row or column wise) and pass this class to your functions to do arthematics.
This approach has advantage of having no memory leaks and also memory continuity (for performance).
And if you are not restricted to use external libraries ... Libraries like Eigen can make it easy for you.
Upvotes: 1
Reputation: 3941
It seems that what you want to do is to handle matrices.
Unfortunatelly, dynamic memory allocation doesn't store the size of the allocated memory.
These are some alternatives:
Then you would need to pass the matrix dimensions as a parameter to your functions. For your example, you could do something like this:
double** add_m(double **m1_, double** m2_, unsigned width, unsigned height)
These classes store the number of elements.
#include <array>
#include <vector>
using namespace std;
// ...
array<array<double, 3>, 3> m1 = {{ {1, 0, 0}, {0, 1, 0}, {0, 0, 1} }};
unsigned height = m1.size();
unsigned width = m1[0].size();
vector<vector<double> > m2 = {{ {0, 1, 0}, {1, 0, 0}, {0, 0, 1} }};
height = m2.size();
width = m2[0].size();
That keeps track of the number of elements and encapsulates the operations that can be done with them.
If you make a quick google search you will find a tone (keywords: linear algebra library).
These are some I tested and liked:
Upvotes: 1