 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
laclac01@yahoo.com Guest
|
Posted: Sat Aug 20, 2005 10:27 am Post subject: newbie dynamic memory problem |
|
|
I wanted to play around and see if I could make a simple little set of
routines that will do simple complex matrix math. I am not very far in
to but already it is crashing. I am sure I am not doing something
correctly so I was hoping someone smarter than I (meaning almost
everyone) could take a look at what I have and tell me what's wrong.
struct complexMatrix
{
float r;
float i;
};
#include<iostream.h>
#include "types.h"
void CmxAlloc(complexMatrix** mat,int rows, int cols);
void CmxFree(complexMatrix** mat);
int main()
{
complexMatrix** my;
CmxAlloc(my,10,10);
my[0][0].i=6; //<- this causes the program to crash
return 0;
}
//*******************************************************
void CmxAlloc(complexMatrix** mat, int rows, int cols)
{
mat = new complexMatrix*[rows];
for(int i = 0; i < rows; i++)
mat[i] = new complexMatrix[cols];
}
//*******************************************************
void CmxFree(complexMatrix** mat)
{
delete [] mat;
}
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Rob Guest
|
Posted: Sat Aug 20, 2005 2:37 pm Post subject: Re: newbie dynamic memory problem |
|
|
[email]laclac01 (AT) yahoo (DOT) com[/email] wrote:
| Quote: | I wanted to play around and see if I could make a simple little set of
routines that will do simple complex matrix math. I am not very far
in to but already it is crashing. I am sure I am not doing something
correctly so I was hoping someone smarter than I (meaning almost
everyone) could take a look at what I have and tell me what's wrong.
struct complexMatrix
{
float r;
float i;
};
#include
#include "types.h"
void CmxAlloc(complexMatrix** mat,int rows, int cols);
|
Change the type of the first argument to ComplexMatrix ***mat
| Quote: | void CmxFree(complexMatrix** mat);
|
Change this to
void CmxFree(ComplexMatrix **mat, int rows);
I'll come back to this below ....
| Quote: |
int main()
{
complexMatrix** my;
CmxAlloc(my,10,10);
|
and this to CmxAlloc(&my, 10, 10);
| Quote: |
my[0][0].i=6; //<- this causes the program to
crash
return 0;
}
//*******************************************************
void CmxAlloc(complexMatrix** mat, int rows, int cols)
{
mat = new complexMatrix*[rows];
for(int i = 0; i < rows; i++)
mat[i] = new complexMatrix[cols];
}
|
Change this function to
void CmxAlloc(complexMatrix ***mat, int rows, int cols)
{
*mat = new complexMatrix*[rows];
for(int i = 0; i < rows; i++)
(*mat)[i] = new complexMatrix[cols];
}
The reason the original form resulted in a failure is that, mat is
passed by value to this function. When you change it within the
function, the change isn't visible to the caller. Using an extra
level of indirection is needed to ensure the changes are visible to the
caller (i.e. the variable my in the main() is changed so it now points
to a @D array)
| Quote: | //*******************************************************
void CmxFree(complexMatrix** mat)
{
delete [] mat;
}
|
This needs to change so it undoes the operations performed by CmxAlloc
....
void CmxFree(complexMatrix** mat, int rows)
{
for (int i = 0; i < rows; ++i)
delete [] mat[i];
delete [] mat;
}
essentially, the principle here is that there needs to be a matching
delete [] for every new []. Hence the loop on deletion. Otherwise
you will have a memory leak.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Jeff Schwab Guest
|
Posted: Sun Aug 21, 2005 2:42 pm Post subject: Re: newbie dynamic memory problem |
|
|
[email]laclac01 (AT) yahoo (DOT) com[/email] wrote:
| Quote: | I wanted to play around and see if I could make a simple little set of
routines that will do simple complex matrix math. I am not very far in
to but already it is crashing. I am sure I am not doing something
correctly so I was hoping someone smarter than I (meaning almost
everyone) could take a look at what I have and tell me what's wrong.
struct complexMatrix
{
float r;
float i;
};
#include<iostream.h
|
#include
| Quote: | #include "types.h"
void CmxAlloc(complexMatrix** mat,int rows, int cols);
void CmxFree(complexMatrix** mat);
int main()
{
complexMatrix** my;
CmxAlloc(my,10,10);
|
The pointer "my" has not been initialized here. Copying an
uninitialized pointer is potentially dangerous, and there is an implicit
copy in passing it by value. It would be better for the allocation
function to return a valid pointer, such that it may be used by the
caller as an initializer:
complexMatrix** my = CmxAlloc(10, 10);
| Quote: | my[0][0].i=6; //<- this causes the program to crash
|
Because in your version, "my" is never initialized. The CmxAlloc
function assigns to a copy of the pointer, not the pointer itself. The
pointer is passed "by value." If you want code in the function body to
modify variables in the caller's stack frame, you can pass arguments "by
reference" instead. Generally, returning the variable's new value is
more appropriate.
| Quote: | return 0;
}
//*******************************************************
void CmxAlloc(complexMatrix** mat, int rows, int cols)
{
mat = new complexMatrix*[rows];
|
This modifies the local copy, not the actual argument.
| Quote: | for(int i = 0; i < rows; i++)
mat[i] = new complexMatrix[cols];
}
//*******************************************************
void CmxFree(complexMatrix** mat)
{
delete [] mat;
}
|
Here you're deleting only one array, whereas you also allocated a
separate array for each row.
If you are not familiar with the std::complex, std::vector, and
std::valarray class templates in the C++ standard library, you may want
to take a look. You should not have to work directly with "new" and
"delete" very often. Also, you may want to change the name of your
"complexMatrix" structure to reflect the concept it represents. Each
instance of the struct represents one complex number, not a matrix.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Greg Guest
|
Posted: Sun Aug 21, 2005 2:56 pm Post subject: Re: newbie dynamic memory problem |
|
|
[email]laclac01 (AT) yahoo (DOT) com[/email] wrote:
| Quote: | I wanted to play around and see if I could make a simple little set of
routines that will do simple complex matrix math. I am not very far in
to but already it is crashing. I am sure I am not doing something
correctly so I was hoping someone smarter than I (meaning almost
everyone) could take a look at what I have and tell me what's wrong.
struct complexMatrix
{
float r;
float i;
};
#include<iostream.h
#include "types.h"
void CmxAlloc(complexMatrix** mat,int rows, int cols);
void CmxFree(complexMatrix** mat);
int main()
{
complexMatrix** my;
CmxAlloc(my,10,10);
my[0][0].i=6; //<- this causes the program to crash
return 0;
}
.... |
I would recommend using a standard library container to hold the
matrix. Doing so greatly simplifies the program's memory management:
#include
struct ComplexNumber
{
float r;
float i;
};
// a vector of vectors of ComplexNumber's makes a ComplexMatrix
typedef std::vector< std::vector ComplexMatrix;
int main()
{
ComplexMatrix my;
my.assign(10, std::vector<ComplexNumber>( 10 ));
my[0][0].i = 6;
...
}
This approach has several advantages: Besides being more compact, the
program is also more clear. There are no pointers to pointers to
pointers to sort through. And the program is safer: there is no risk of
a memory leak because no memory was explicitly allocated.
Greg
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Yuri Khan Guest
|
Posted: Mon Aug 22, 2005 10:05 am Post subject: Re: newbie dynamic memory problem |
|
|
In fact, I would go even further and suggest using standard complex
numbers, std::complex<float> or std::complex<double>, along with
standard vectors of vectors. Or, if I were looking for a low-overhead
rectangular matrix, I would implement a rectangular array template:
template <typename T>
class array2d
{
public:
array2d(size_t rows, size_t cols, T initial = T())
: rows_(rows), cols_(cols), data_(rows * cols, initial)
{}
const T& operator()(size_t row, size_t col) const
{
assert(0 <= row && row < rows_ && 0 <= col && col < cols_);
return data_[row * cols_ + col];
}
T& operator()(size_t row, size_t col)
{
assert(0 <= row && row < rows_ && 0 <= col && col < cols_);
return data_[row * cols_ + col];
}
private:
size_t rows_;
size_t cols_;
std::vector
};
One can add proxy classes to allow the usual syntax of a[i][j]; I find
a(i, j) sufficient unless I later need iterators. And it is an entirely
different question as to what kind of iterators one might want over a
2D array.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|