Operator Overload with Arrays

Hello everyone,
I am working on a program that takes two matrices and adds them together. My program compiles fine but there is a logical error. I'm confident that I assigned my arrays to my functions correctly, but I do not get the correct result when I use the overloaded + operator. When I display my result, I just get "1.06725e+263" repeated in a 4x4 array. In the interest of making my post look clean I'll post pieces of it.
Please help me understand what I am doing wrong. Any help is greatly appreciated!

This is the constructor that assigns the arrays to the class.
1
2
3
4
5
6
7
8
9
10
11
          matrices::matrices(double one[][4])
          {
              array[4][4] = one[4][4];
              for (int y = 0; y < 4; ++y )
              {
                   for (int x = 0; x < 4; ++x )
                   {
                   array[x][y] = one[x][y];                 
                   }
               } 
          } 


This is my overloaded >> operator:
1
2
3
4
5
6
7
8
9
10
11
12
          ostream& operator <<(ostream& outs, const matrices& sums)
          {
               for (int y = 0; y < 4; ++y )
               {
                   for (int x = 0; x < 4; ++x )
                   { 
                       outs << sums.get_array()<< " ";
                   }
                   outs << endl;
               }
               return outs;
           }


This is my overloaded operator.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
          matrices operator+(const matrices& param1, const matrices& param2)
          {
                   double adds[4][4];
                   for (int y = 0; y < 4; ++y )
                   {
                       for (int x = 0; x < 4; ++x )
                       {
                           adds[x][y] = param1.get_array() + param2.get_array();                       
                       }   
                   }
                   matrices sum(adds); // This is where I think the problem is
                   return sum; // Also here
          }



This is my header file.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
namespace matrix
{
      class matrices
      {
            public:
                   matrices() {};
                   matrices(double [][4]);
                   void greeting();
                   void test(double [][4]);
                   double get_array() const {return array[4][4];} //This might be a problem too but I am not sure.
                   friend ostream& operator <<(ostream & outs, const matrices& sums);            
            private:
                    double array[4][4];
      };
            matrices operator+(const matrices& param1, const matrices& param2);                                   

}


A condensed version of my driver program:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    //how array1 and array2 are read from file.
    double array1[4][4], array2[4][4];    

    for (int y = 0; y < 4; ++y )
    {
	    for (int x = 0; x < 4; ++x )
	    {
		    infile >> array1[x][y]; //same for array2		    
        }
    }
    matrices one(array1);
    matrices two(array2);
    matrices sums;
    sums = one + two;
    cout << sums << endl;
Last edited on
return array[4][4];} //This might be a problem

It certainly is: there is no array[4][4]. The valid elements of a 4x4 array range from array[0][0] to array[3][3]. But even if you change that, your get_array will only ever be able to return a single double.

To make a matrix useful, I would start by giving it indexed accessors:

you could go the boost.ublas way and use round parentheses for access, such as

1
2
3
4
5
6
7
8
class matrices {
// other members
    double& operator()(size_t row, size_t col) { return array[row][col]; }
    double operator()(size_t row, size_t col) const { return array[row][col]; }
};
// in main:
one(1, 2) = x; // calls the non-const version
std::cout << one(1, 2); // calls the const version 


or if you like your brackets, you would have to write operator[] that returns something on which you could call another operator[]. If you feel like confusing a teacher or two, make the first operator[] return an array and let the built-in operator[] sort out the second dimension:

1
2
3
4
5
6
7
8
class matrices {
// other members
    double const (&operator[](size_t i) const)[4] { return array[i]; }
    double (&operator[](size_t i))[4] { return array[i]; }
};
// in main:
one[1][2] = x; // calls the non-const version
std::cout << one[1][2]; // calls the const version 
Last edited on
Review the basics
int array[42]; declares an array that can hold 42 elements
array[42] would try to access the 43th element (remember that index starts at 0). That is outside the bounds of the array, is a logic error and the result is undefined behaviour.

So doing array[4][4] = one[4][4]; is wrong


double get_array() const {return array[4][4];}
Read carefully. Returns one number, that number is always stored in the same position (4,4), and it's outside the bounds of the array.

I would suggest to change your function to
1
2
3
double get_array(int x, int y) const {
   return array[x][y];
}
@Chubbi
You're right, that was the problem. Thanks for the response!

@ne555
array[4][4] = one[4][4]; is definitely wrong. I took it out a while ago when I realized my mistake and have no idea how it ended up in the post. User error.

Changing my function to what you suggested worked. Your explanation made a lot of sense and made me realize what I was doing wrong. Thanks for the help! You saved me a lot of frustration!
Last edited on
Topic archived. No new replies allowed.