0

I was creating an Abstract data type for matrix operation with the help of template in c++. this is the code for the class is as follows

template <typename item_type>
class matrix
{
private:
    item_type **data;

public:
    size_t *shape;

    matrix(size_t n_rows, size_t n_cols)
    {
        // allocates a memory block of item_type of size n_rows by n_cols and initializes it with zeros and allocates memory for shape array and saves n_rows in shape[0] and n_cols in shape[1]. 
    }

    ~matrix()
    {
        for (size_t i = 0; i < this->shape[0]; i++)
        {
            free(data[i]);
        }
        free(this->data);
        free(this->shape);
    }

the code is pretty standard and contains a constructor and a destructor. When I overload the operator '+' like this the code works fine.

friend matrix<item_type> operator+(matrix<item_type> m1 ,matrix<item_type> m2)
{
   matrix<item_type>res(m1.shape[0] , m1.shape[1]);
   for (size_t i = 0; i < m1.shape[0]; i++)
            {
                for (size_t j = 0; j < m1.shape[1]; j++)
                {
                    res[i][j] = m1[i][j] + m2[i][j];
                }
            }
            return res;
}

as expected the code works perfectly fine and gives the expected result but when I overloaded the operator '+' with an if condition as :

friend matrix<item_type> operator+( matrix<item_type> m1,  matrix<item_type> m2)
    {
        if (m1.shape[0] == m2.shape[0] && m1.shape[1] == m2.shape[1])
        {
            matrix<item_type> res(m1.shape[0], m1.shape[1]);
            for (size_t i = 0; i < m1.shape[0]; i++)
            {
                for (size_t j = 0; j < m1.shape[1]; j++)
                {
                    res[i][j] = m1[i][j] + m2[i][j];
                }
            }
            return res;
        }
        else
        {
           // try to broadcast etc...
        }
    }
    

The returned matrix contains garbage values in both shape array and data array. but when I removed the destructor both code works perfectly fine. my understanding from this was that the destructor was getteing called even before the res was returned in the second case. I want the second code to work correctly with destructor also working. What am I doing wrong here???

Naval
  • 31
  • 3
  • The more involved question is not why one version fails, but why the other version works. That gets into [copy elision and return value optimization](https://stackoverflow.com/questions/12953127/what-are-copy-elision-and-return-value-optimization). – JaMiT Feb 28 '21 at 06:54
  • You shouldn't really be using `malloc` and `free` in C++, rather use `new[]` and `delete[]`. And even better use a smart pointer like [`std::unique_ptr`](https://en.cppreference.com/w/cpp/memory/unique_ptr). And best is to not use pointers at all and instead use [`std::vector`](https://en.cppreference.com/w/cpp/container/vector), which will also solve your problem since then you can follow the rule of *zero*. – Some programmer dude Feb 28 '21 at 06:54
  • You should not use `free` or `malloc` in C++ – M.M Feb 28 '21 at 07:04

0 Answers0