Passing a pointer to a C ++ 2D array

I have had a problem with this for quite some time: I have a fixed dimensional 2D array as a member of a class.

class myClass { public: void getpointeM(...??????...); double * retpointM(); private: double M[3][3]; }; int main() { myClass moo; double *A[3][3]; moo.getpointM( A ); ??? A = moo.retpointM(); ??? } 

I want to pass a pointer to an external matrix M This is probably very simple, but I just can't find the right combination of & and * , etc.

Thanks for the help.

+6
c ++ arrays multidimensional-array pointer-to-member
source share
7 answers

double *A[3][3]; is a two-dimensional array of double * s. You want double (*A)[3][3]; .

Then note that A and *A and **A all have the same address, only different types.

Creating a typedef can simplify:

 typedef double d3x3[3][3]; 

This is C ++, you should pass the variable by reference, not a pointer:

 void getpointeM( d3x3 &matrix ); 

Now you do not need to use parens in type names, and the compiler will make sure that you pass the array to the correct size.

+9
source share

Your intention is not clear. What do getpointeM do? To return the pointer to the internal matrix (through the parameter) or to return a copy of the matrix?

To return a pointer, you can do this

 // Pointer-based version ... void getpointeM(double (**p)[3][3]) { *p = &M; } ... int main() { double (*A)[3][3]; moo.getpointM(&A); } // Reference-based version ... void getpointeM(double (*&p)[3][3]) { p = &M; } ... int main() { double (*A)[3][3]; moo.getpointM(A); } 

For retpointM declaration will look like this

 ... double (*retpointM())[3][3] { return &M; } ... int main() { double (*A)[3][3]; A = moo.retpointM(); } 

This is pretty hard to read. You can make it a lot clearer if you use typedef-name for your array type

 typedef double M3x3[3][3]; 

In this case, the above examples are converted to

 // Pointer-based version ... void getpointeM(M3x3 **p) { *p = &M; } ... int main() { M3x3 *A; moo.getpointM(&A); } // Reference-based version ... void getpointeM(M3x3 *&p) { p = &M; } ... int main() { double (*A)[3][3]; moo.getpointM(A); } // retpointM ... M3x3 *retpointM() { return &M; } ... int main() { M3x3 *A; A = moo.retpointM(); } 
+3
source share

Short answer: you can get double * before the start of the array:

 public: double * getMatrix() { return &M[0][0]; } 

Outside the class, however, you cannot trivially turn double * into another 2D array directly, at least not in the template I saw.

You can create a 2D array basically, though (double A [3] [3]) and pass this to the getPoint method, which could copy the values ​​into the passed array. This will give you a copy, which may be what you want (instead of the original, modifiable data). The disadvantage is that you have to copy it, of course.

0
source share

In your main() function:

 double *A[3][3]; 

creates a 3x3 array of double* (or paired pointers). In other words, 9 x 32-bit contiguous memory words for storing 9 memory pointers.

There is no need to make a copy of this array in main() if the class is not destroyed, and you still want to access this information. Instead, you can simply return a pointer to the beginning of this member array.

If you want to return a pointer to the internal member of the class, you really only need one pointer value in main() :

 double *A; 

But if you pass this pointer to a function and you need a function to update its value, you will need a double pointer (which will allow the function to return the actual value of the pointer back to the caller:

 double **A; 

And inside getpointM() you can just point A to the inner member ( M ):

 getpointeM(double** A) { // Updated types to make the assignment compatible // This code will make the return argument (A) point to the // memory location (&) of the start of the 2-dimensional array // (M[0][0]). *A = &(M[0][0]); } 
0
source share
 class myClass { public: void getpointeM(double *A[3][3]) { //Initialize array here } private: double M[3][3]; }; int main() { myClass moo; double *A[3][3]; moo.getpointM( A ); } 
0
source share

You can take the code in your main function, which works with a two-dimensional array of doubles, and move it to myClass as a member function. Not only would you not have to cope with the difficulties of passing a pointer to this 2D array, but the code open for your class would no longer need to know the details of how your class implements A, since they will now call the function in myClass and resolve it do. If, say, you later decided to allow variable sizes A and decided to replace the array with vector of vector s, you would not need to rewrite the calling code to make it work.

0
source share

Make M public, not private. Since you want to allow access to M via a pointer, M is still not encapsulated.

 struct myClass { myClass() { std::fill_n(&M[0][0], sizeof M / sizeof M[0][0], 0.0); } double M[3][3]; }; int main() { myClass moo; double (*A)[3] = moo.M; double (&R)[3][3] = moo.M; for (int r = 0; r != 3; ++r) { for (int c = 0; c != 3; ++c) { cout << A[r][c] << R[r][c] << ' '; // notice A[r][c] and R[r][c] are the exact same object // I'm using both to show you can use A and R identically } } return 0; } 

I would generally prefer R over A, because all lengths are fixed (A can potentially point to double[10][3] if this is a requirement), and the link will usually lead to clearer code.

0
source share

All Articles