| 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. |