0

I have a C++ class Matrix2 which contains a public method, foo(), and a protected member, m, declared here

 public:

 void foo();

 protected:

 float m[2][2];

Assume that the entire contents of the array m are zero initialized in the constructor.

Inside another function somewhere, I declare a Matrix2 on the stack.

Matrix2 MAT;

Then, in that same function, I call some function, foo, a public function in the Matrix2 class.

 MAT.foo();

Inside foo(), I set

float ** u = (float **) m;

afterwards, within foo, I print out the following values.

 cout << "m :: " << u << endl;
 cout << "u :: " << m << endl;
 cout << "&m[0][0] :: " << &(m[0][0]) << endl;
 cout << "m[0][0] :: " << m[0][0] << endl;
 cout << "u[0][0] :: " << u[0][0] << endl;

The results: u's mem address is the same as m's, as well as the same as &(m[0][0]).

Dereferencing m using m[0][0], the value prints out fine, as expected.

However, dereferencing u using u[0][0], the program crashes and is unable to read the memory, even though the pointer supposedly points to the same location.

Any ideas as to why this is?

Ami Tavory
  • 74,578
  • 11
  • 141
  • 185
jshamble
  • 391
  • 2
  • 14
  • 2
    An array of arrays of some type is *not* the same as a pointer to pointer to some type. See e.g. [this old answer of mine](http://stackoverflow.com/questions/18440205/casting-void-to-2d-array-of-int-c/18440456#18440456) for an explanation. – Some programmer dude Dec 27 '15 at 07:42
  • Your `m` is not an array of pointers to floats; it is a two-item array of two-item arrays of floats, so the symbol `m` is `(float [2])*`, not `float**` type. If you want to dump the array values without using an array syntax you might just cast `m` as `float*`, assuming the whole array contents is stored in consecutive locations in memory. But that is asking for problems... – CiaPan Dec 27 '15 at 07:51
  • You are making a fatal mistake in your approach already: Casting. If the two sides of an assignment don't match, you should think about why that is the case and change either side to the correct type instead of applying brute force (which is what a C-style cast is equivalent to) in order to make the compiler ignore this error. – Ulrich Eckhardt Dec 27 '15 at 08:06
  • Take the cast away. Recompile. What compiler error do you get? A cast is not going to change what the compiler error is telling you. All you did when you used the cast was make the error **message** go away -- the pointers are still incompatible and you see the results when you run the program. – PaulMcKenzie Dec 27 '15 at 08:16

1 Answers1

0

It is true that arrays and pointers are somewhat interchangeable, but they need to refer to the same element type. Here, m is an array of [arrays of length 2 of float]. If you want to use a pointer, simply use the correct element type:

1 typedef float float_arr[2];
2 
3 
4 int main()
5 {
6     float m[2][2];
7                                                                                                                                                                                                          
8     float_arr *p = m;
9    
10     return 0;
11 }
Ami Tavory
  • 74,578
  • 11
  • 141
  • 185
  • Learn when you need to use casts. Your problem is `float ** u = (float **) m;`. The fact you needed a cast here to make it compile, should have been a warning that you had things wrong. – Martin Bonner supports Monica Dec 27 '15 at 09:10