Connecting Tech Pros Worldwide Forums | Help | Site Map

Pointer to a class with dynamic memory

E G
Guest
 
Posts: n/a
#1: Jul 22 '05
Hi

I have a class that is an expanded version of the following:

class Matrix
{
private:
float **_A;
unsigned _rows,_cols;

public:
Matrix():_A(0),_rows(0),_cols(0){}
Matrix(unsigned const rows,unsigned const cols):_A(0),_rows(0),_cols(0)
{
if(rows>0 && cols>0){
_A=new float*[rows];
if(_A==0)
throw "No Memory Left";
_A[0]=new float[rows*cols];
if(_A[0]==0){
delete[] _A;
_A=0;
throw "No Memory Left";
}
if(rows>1)
for(unsigned i=1;i<rows;i++)
_A[i]=_A[0]+ i*cols;
_rows=rows;
_cols=cols;
memset(_A[0],0,rows*cols*sizeof(Type));
}
}
~Matrix()
{
if(_A != 0){
if(_A[0] != 0)
delete [] _A[0];
delete [] _A;
}
_A=0;
_rows=0;
_cols=0;
}
Matrix & operator=(Matrix const& M)
{
if(this != &M){
if(this->_A!=0){
delete[] this->_A[0];
delete[] this->_A;
_rows=0;
_cols=0;
}
this->_A=0;
this->_rows=M._rows;
this->_cols=M._cols;
this->_A=new float*[this->_rows];
if(this->_A==0){
this->_rows=0;
this->_cols=0;
throw "No Memory Left";
}
this->_A[0]=new float[this->_rows*this->_cols];
if(this->_A[0]==0){
delete[] this->_A;
this->_rows=0;
this->_cols=0;
this->_A=0;
throw "No Memory Left";
}
if(this->_rows>1)
for(unsigned i=1;i<this->_rows;i++)
this->_A[i]=this->_A[0]+ i*this->_cols;
memcpy(this->_A[0],M._A[0],
this->_rows*this->_cols*sizeof(float));
}
return *this;
}
}

when I use this class in the following program:

in main(int argc,char **argv)
{
Matrix *pfM;
{
Matrix fM(4,3);

Mike Wahler
Guest
 
Posts: n/a
#2: Jul 22 '05

re: Pointer to a class with dynamic memory



"E G" <egarduno@ucsd.edu> wrote in message news:403BE120.6010505@ucsd.edu...[color=blue]
> Hi[/color]

This is not a chat room. Please allow time for your message
to propagate across the multitude of Usenet servers. This can
be from a few minutes to several days.

About your question:

As Julie points out, do *not* try to use 'delete' on
memory not allocated with 'new'. An 'auto' storage class
object will be automatically destroyed (after its
destructor is called, if applicable) when program flow
leaves the block where it is defined.

-Mike


Rolf Magnus
Guest
 
Posts: n/a
#3: Jul 22 '05

re: Pointer to a class with dynamic memory


E G wrote:
[color=blue]
> Hi
>
> I have a class that is an expanded version of the following:
>
> class Matrix
> {
> private:
> float **_A;[/color]

_A is reserverd for the implementation. You are not allowed to use any
identifiers that begin with an underscore followed by an uppercase
letter for your own code.
[color=blue]
> unsigned _rows,_cols;
>
> public:
> Matrix():_A(0),_rows(0),_cols(0){}
> Matrix(unsigned const rows,unsigned const
> cols):_A(0),_rows(0),_cols(0)
> {
> if(rows>0 && cols>0){
> _A=new float*[rows];
> if(_A==0)
> throw "No Memory Left";
> _A[0]=new float[rows*cols];
> if(_A[0]==0){
> delete[] _A;
> _A=0;
> throw "No Memory Left";
> }
> if(rows>1)
> for(unsigned i=1;i<rows;i++)
> _A[i]=_A[0]+ i*cols;
> _rows=rows;
> _cols=cols;
> memset(_A[0],0,rows*cols*sizeof(Type));
> }
> }
> ~Matrix()
> {
> if(_A != 0){
> if(_A[0] != 0)
> delete [] _A[0];
> delete [] _A;
> }
> _A=0;
> _rows=0;
> _cols=0;
> }
> Matrix & operator=(Matrix const& M)
> {
> if(this != &M){
> if(this->_A!=0){
> delete[] this->_A[0];
> delete[] this->_A;
> _rows=0;
> _cols=0;
> }
> this->_A=0;
> this->_rows=M._rows;
> this->_cols=M._cols;
> this->_A=new float*[this->_rows];
> if(this->_A==0){
> this->_rows=0;
> this->_cols=0;
> throw "No Memory Left";
> }
> this->_A[0]=new float[this->_rows*this->_cols];
> if(this->_A[0]==0){
> delete[] this->_A;
> this->_rows=0;
> this->_cols=0;
> this->_A=0;
> throw "No Memory Left";
> }
> if(this->_rows>1)
> for(unsigned i=1;i<this->_rows;i++)
> this->_A[i]=this->_A[0]+ i*this->_cols;
> memcpy(this->_A[0],M._A[0],
> this->_rows*this->_cols*sizeof(float));
> }
> return *this;
> }
> }
>
> when I use this class in the following program:
>
> in main(int argc,char **argv)
> {
> Matrix *pfM;
> {
> Matrix fM(4,3);
> .
> .
> operations
> .
> .
> pfM=&fM; <--------- The destructor for Matrix is called and
> pfM->_A=0x0 }[/color]

Any variable defined in a block is destroyed at the end of that block,
so fM doesn't exist anymore and you must not attempt to access it.
[color=blue]
> .
> .
> operations <-------- Segmentation fault SIGSEGV, since pfM->_A=0x0
> .
> .
> delete pfM;[/color]

You can only call delete on a pointers you got from new.
[color=blue]
> return 0;
> }
>
> I know I could avoid the proglem by operating directly with pfM=new
> Matrix(4,3) but I would like to know if there is a way to solve the
> problem by adding some extra code to this example.[/color]

You could create another Matrix object outside the block and copy fM
into it, or just let your code block work on a Matrix object that is
defined externally. Btw, your class is missing a copy constructor.
Remember the Rule of Three: If you need a copy constructor, assingment
operator or destructor, you probably need all three of them.

Closed Thread