Questions about pointers to pointers.

Started by
10 comments, last by Zahlman 17 years, 11 months ago
Hello. I'm trying to design a MATRIX class as a means to getting a better understanding of matrices. I figured that, since I don't know the dimensions of the matrices beforehand, it would be best to use a double-pointer for the actual matrix data components. At runtime, the user will enter the values for m and n and the necessary memory will be allocated at that time using new. But my head is spinning a bit as I try to grasp the concept of pointers-to-pointers. I currently have a member function called CreateEmptyMatrix() that takes the values of m and n and allocates the necessary memory and initialized each componant to 0. The name of the data member I'm using to hold the components of the matrix is data and I've declared it as such: double ** data. It's currently set up to first check to make sure than the data members m and n are nonzero, positive numbers. If so, it first creates the "rows" by using this statement: data = new double*[m]; I figure this will make sure that data is like an array of pointers to doubles, which represent the rows. I then use a for loop to go through to each row, and set aside enough memory to hold each component in each row:

for(int index = 0; index < m; index++)
{

     *data[index] = new double[n];
      
}
So, this basically creates an array of doubles for each row. I just want to make sure that my syntax is correct because I'm not 100% confident that I'm doing the pointer stuff correctly. I'd try it out myself, but it will be a while before I can compile my code. Also, I'm wondering what the best way to handle the destructor is. Should I have it just go through each row and call delete []? [Edited by - uncle_rico on May 21, 2006 8:40:15 PM]
Advertisement
*data[index] = new float[n];

should probably be

data[index] = new double[n];

Quote:
Also, I'm wondering what the best way to handle the destructor is. Should I have it just go through each row and call delete []?

That should be sufficient I think. Dont forget to finish off with
delete [] data;
data[index] = new float[n]; *

That should do it. You don't need to dereference data. Indexing the array does that.

data[index] => holds a pointer to double **

it's equivalent to *(data+index)

*, ** per what pulpfist wrote
"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man
Oh yes, that's right. I meant "double." I'll edit that in.

This class is actually templated, and I thought about using TEMPLATECLASS as my data type in my post, but I thought that'd be too confusing to read.
Quote:Original post by LessBread
data[index] = new float[n]; *

That should do it. You don't need to dereference data. Indexing the array does that.


Oh man, I totally forgot. Thanks!
Do you guys find it less confusing to change the matrix convention to [column][row] to match the C++ array convention, or is better just to stick to the way matrices are done normally ([rows][column])?
I always get confused when I have to confront myself with that question

I think Im using [row][column] intuitively
For reasons of efficiency, you'll probably want to your matrices stored in such a way that the contents of the columns are consecutive in memory. This is opposite of the standard C++ notation so it may take you a little while to train your brain to think in those terms. Both OpenGL and DirectX store matrices this way internally (although they use different notation in their respective documentation) to optimise matrix-vector multiplication which is the primary calculation in graphics applications. For more scientific calculations, your chosen notation will have little bearing since you'd want to impliment a fast transpose function in either case. Certain equations will favor one or the other due to memory access patterns. Take the matrix-matrix multiplication for instance, where transposing one of the matrices will allow linear walking of both matrices in memory and also allow the computation to take advantage of SIMD instucions such as SSE or altivec.

throw table_exception("(? ???)? ? ???");

If I were you, I would not use a pointer to pointer but a static array in a templated matrix class.

template<unsigned n, unsigned m> class Matrix{    float mat[n*m];    ...}
Tchou kanaky ! tchou !
Quote:Original post by Mawww
If I were you, I would not use a pointer to pointer but a static array in a templated matrix class.

template<unsigned n, unsigned m> class Matrix{    float mat[n*m];    ...}


But then m and n would have to be constants. In this case, I do not know what the dimensions will be until runtime.

This topic is closed to new replies.

Advertisement