1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Development C++ Problem (Classes/pointers)

Discussion in 'Software' started by Flax, 7 Aug 2004.

  1. Flax

    Flax What's a Dremel?

    Joined:
    24 Jun 2002
    Posts:
    300
    Likes Received:
    1
    Been having a bit of trouble with something this morning...

    I was implementing a matrix class to try and get my head around the maths a bit better, and am stuck with a weird problem.

    The functions seem to be working fine when I use them to initialise variables (type: class matrix), but as soon as I use them with a variable that is already assigned I end up with junk values, and later a crash.

    Stepping through the code in the debugger, what seems to be happening is:
    Code:
    matrix C = A+B;
    ...
    matrix matrix::operator+(matrix operand)
    {
    	if (cols != operand.cols || rows != operand.rows)	// Check matrices are conformable
    		return operand;
    
    	matrix ret(rows,cols);
    	
    	for (int i = 1; i <= rows; i++)
    	{
    		for (int j = 1; j <= cols; j++)
    		{
    			ret(i,j) = (*this)(i,j) + operand(i,j);
    		}
    	}
    	
    	return ret;
    }
    
    Copy of B is made with copy constructor to be passed to the operator+ function.
    ...
    Variable ret created, peened by the loop
    Copy of ret is made with copy constructor, to be passed back to "C ="
    Operand, and ret go out of scope so destructors called.

    That all makes sense... And then it goes weird.
    Code:
    C = A*B;
    ...
    matrix matrix::operator*(matrix operand)
    {
    	if (cols != operand.rows)	// Check matrices are conformable
    		return operand;
    
    	matrix ret(rows,operand.cols);
    
    	for (int i = 1; i <= rows; i++)
    	{
    		for (int j = 1; j <= operand.cols; j++)
    		{
    			float sum = 0;
    			for (int k = 1; k <= cols; k++)
    			{
    				sum += (*this)(i, k) * operand(k, j);
    			}
    			ret(i,j) = sum;
    		}
    	}
    	return ret;
    }
    
    Once again a copy of B is made to be passed as parameter,
    Ret created, filled
    Copy of Ret created to be passed back to "C = "
    (operator* Function returns)
    Destructor called for Ret, and operand...
    Destructor called for variable C/the object that was just returned

    The destructor frees the dynamic memory used to store the values for the matrix in, and because its compiled in debug mode the data in memory is set to some extreme value (hence the wammy values).
    The destructor is then called again where it would be expected at the end of the program, but as it is trying to free unallocated memory it cries and we get windows error messages jumping up.

    Can anyone spot what I'm doing wrong? Could be a fundemental misunderstanding on how classes work :worried: or perhaps I'm doing something silly?

    Heres the rest of the code that hasn't already been posted:
    Code:
    Matrix.h:
    
    class matrix
    {
    public:
    
    	matrix(int rows, int cols);	// Constructor to create matrix of specified size
    	matrix(const matrix &orig);
    
    	~matrix(){
    			delete [] values;
    	}
    
    	float& operator()(int i, int j);	// Returns value at m[i,j]
    
    	matrix operator+(matrix operand);
    	matrix operator*(matrix operand);
    
    private:
    	int rows; // Height of the matrix
    	int cols;	// Width of the matrix
    
    	float *values;
    };
    
    matrix::matrix(int rows, int cols)
    {
    	this->rows = rows;
    	this->cols = cols;
    
    	values = new float[rows*cols];
    
    }
    
    matrix::matrix(const matrix &orig)
    {
    	rows = orig.rows;
    	cols = orig.cols;
    
    	values = new float[rows*cols];
    	
    	memcpy(values, orig.values, rows*cols*sizeof(float));
    
    }
    
    float& matrix::operator() (int i, int j)
    {
    	/*
    	 11 12 13
    	 21 22 23
    	 31 32 33
    	 */
    	return values[(i-1)*cols + (j-1)];
    }
    main.cpp:
    
    void main()
    {
    	cout << "Matrix Test" << endl;
    
    
    	matrix A(2,2);
    	A(1,1) = 1;	A(1,2) = 2;
    	A(2,1) = 3;	A(2,2) = 4;
    
    	cout << "A:" << endl;
    	cout << A(1,1) << " " << A(1,2) << endl;
    	cout << A(2,1) << " " << A(2,2) << endl;
    
    	matrix B(2,2);
    	B(1,1) = 5;	B(1,2) = 6;
    	B(2,1) = 7;	B(2,2) = 8;		
    	
    	cout << "\nB:" << endl;
    	cout << B(1,1) << " " << B(1,2) << endl;
    	cout << B(2,1) << " " << B(2,2) << endl;
    
    	matrix C = A+B;
    
    	cout << "\nA + B = C:" << endl;
    	cout << C(1,1) << " " << C(1,2) << endl;
    	cout << C(2,1) << " " << C(2,2) << endl;
    
    	C = A*B;
    
    	cout << "\nA * B = C:" << endl;
    	cout << C(1,1) << " " << C(1,2) << endl;
    	cout << C(2,1) << " " << C(2,2) << endl;
    
    }
    
     
  2. Flax

    Flax What's a Dremel?

    Joined:
    24 Jun 2002
    Posts:
    300
    Likes Received:
    1
    All fixed

    Gave it a break then came back to it, and problem solved.
    I needed to overload the = operator to stop it from messing up the pointers for the values variable. Woops
     

Share This Page