# Newbie question: Right way of creating a matrix using the new operator?

Show 80 post(s) from this thread on one page
Page 1 of 2 12 Last
• 04-24-2005
cppboard05
Newbie question: Right way of creating a matrix using the new operator?
Hi,

I'm trying to dynamically create a matrix, let's call it M, which can be accesed using the usual M[i][j] notation. That's it, it should behave as if I had declared it as a double M[5][5], except the size should be a variable rather than 5.

This is the simplest example:

Code:

```#include <iostream.h> void createMatrix(int size) {         double *M = new double[size*size]; // doesn't work :(         /*         // This does work, but is really awful... there's got to be a better way!         double **M = new double*[size];         for (int k = 0; k < size; k++)                 M[k] = new double[size];         */         // this MUST work:         for(int i = 0; i < size; i++)                 for(int j = 0; j < size; j++)                         M[i][j] = 3.141592;        // whatever         delete[] M; } int main() {         int n;         cout << "Size of the matrix? ";         cin >> n;         createMatrix(n);         return 0; }```
Please, tell me there's a better solution that the horrible hack I did!!

:)
• 04-25-2005
prog-bman
The double pointer method is the only way I know that you can dynamically create a 2*2 array besides using a container. Oh and it is <iostream> and not <iostream.h> and put it in the std namespace.
• 04-25-2005
Thantos
Code:

```void createMatrix(int size) {         double **M =  new double*[size];         for(int i=0; i < size; i++)                 M[i] = new double[size];         // Do something with it here         for(int i=0; i < size; i++)                 delete[] M[i];         delete[] M; }```
Another why using vectors:
Code:

```void createMatrix(int size) {         vector< vector<double> > M;         M.resize(size);         for(int i=0; i < size; i++)                 M[i].resize(size); }```
• 04-25-2005
cppboard05
Thanks for the reply... does anybody else know if the right way of dynamically creating a n*n array is:

Code:

```        double **M = new double*[size];         for (int k = 0; k < size; k++)                 M[k] = new double[size];```
Because this is really ugly syntax, and, if I understand memory allocation correctly, awfully inefficient because not only we have significant overhead allocating memory in a loop but we'll also, with all probability, end with a fragmented matrix, as there's no reason to expect those allocations will put our new arrays contiguously in memory.

This program is supposed to use a very large matrix.
• 04-25-2005
cppboard05
Quote:

Originally Posted by Thantos
Code:

```void createMatrix(int size) {         double **M =  new double*[size];         for(int i=0; i < size; i++)                 M[i] = new double[size];         // Do something with it here         for(int i=0; i < size; i++)                 delete[] M[i];         delete[] M; }```

Thanks for the correction... one memory leak less :)

[QUOTE]
Another why using vectors:
Code:

```void createMatrix(int size) {         vector< vector<double> > M;         M.resize(size);         for(int i=0; i < size; i++)                 M[i].resize(size); }```
This is much better... but, can I access individual members of M with the M[i][j] notation if I use this? Also, is this what you guys mean when you said "using a container"?
• 04-25-2005
7stud
Quote:

but, can I access individual members of M with the M[i][j] notation if I use this?
...and how many seconds would that take to test? :confused:

Quote:

Also, is this what you guys mean when you said "using a container"?
Yes.
• 04-25-2005
cppboard05
Quote:

Originally Posted by 7stud
...and how many seconds would that take to test? :confused:

Ok, I tested it... seems to work great :D

But what about efficiency? It seems to me this is the same thing I was doing initially but with a better syntax, which probably means the overhead and fragmentation problems I wrote about are still there...

And there's no need to deallocate memory while using containers... right?
• 04-25-2005
prog-bman
Ya all of the deallocation is taken for you with the containers within the destructor of the container you are using. I am not sure what you mean about fragmentation when using dynamic memory but I don't think so.
• 04-25-2005
Micko
Because calls of new and delete are generally slow, thers is one way I like:
Code:

```        //Allocate the actual data         int* rawData = new int[rows*cols];           //Allocate pointers to the data         int** data = new int*[rows];           //Point the pointers into the data         for (int i=0; i < rows; ++i)             data[i] = &rawData[cols*i];```
I hope this code will not confuse you.

- Micko
• 04-25-2005
7stud
Quote:

But what about efficiency? It seems to me this is the same thing I was doing initially but with a better syntax, which probably means the overhead and fragmentation problems I wrote about are still there...
That's what I was wondering about, too.

Quote:

And there's no need to deallocate memory while using containers... right?
The class takes care of all that: you can expand or contract the vector at will as well using insert(), pushback(), and erase().
• 04-25-2005
7stud
Quote:

I am not sure what you mean about fragmentation when using dynamic memory but I don't think so.
I think he suspects that since the allocations take place at different times, e.g. one allocation per loop iteration, that the allocated memory will not necessarily be contiguous. My first question is: since dynamically allocated memory is allocated on the heap, is there a way for any other processes to allocate memory on the heap in between a for-loops allocations? My second question is: does it even matter whether the memory is contiguous or not. The look up is done with a pointer, so is it even relevant where the actual arrays are located?
• 04-25-2005
joshdick
Arrays are always contiguous in memory. And yes, it does matter for arrays. When you code something like a[5], that tells the computer to go start at *a, or a[0], and go over five. Therefore, those array indices must be contiguous in memory.

Container classes are another story, however. You could implement a container to act like an array that's really a linked list or hash under the hood.
• 04-25-2005
Thantos
A multi dimensional array allocated like this probably won't be contigious. But thats ok as each dimension will be contigious onto itself. It only becomes a problem when you try to treat a multi dimensional array as a single dimensional array.

Quote:

Container classes are another story, however. You could implement a container to act like an array that's really a linked list or hash under the hood.
Except vectors require that &v[1] == (&v[0] + 1)
• 04-25-2005
joshdick
Quote:

Originally Posted by Thantos
Except vectors require that &v[1] == (&v[0] + 1)

I wasn't talking about the vector class. I know that the STL containers have restrictions on speed and space and such. That doesn't stop someone from creating a class with the much of the interface of a vector with another underlying container -- even if that does mean differing performance.

I was just trying to point out that when using a class, one shouldn't overly concern oneself with the underlying structure.
• 04-25-2005
Perspective
>>double *M = new double[size*size]; // doesn't work :(

This does work if you index it properly. instead of indexing M[x][y], you use M[ x*size + y ].
Show 80 post(s) from this thread on one page
Page 1 of 2 12 Last