Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7675841
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 31, 20262026-05-31T17:03:35+00:00 2026-05-31T17:03:35+00:00

This is probably just me being stupid somehow or the other, but I am

  • 0

This is probably just me being stupid somehow or the other, but I am relatively new to C++, so forgive me the idiocy. I’m trying to teach myself how to use operators. I’ve defined a very basic operator as follows:

Matrix::Matrix operator+(Matrix a1, Matrix a2) {
    if(a1.rows != a2.rows || a1.cols != a2.cols) {
        std::cout << "ERROR: Attempting to add matrices of non-equal size." << std::endl;
        exit(6);
    }

    int i, j;

    Matrix c(a1.rows, a1.cols);

    for(i = 0; i < a1.rows; i++)
        for(j = 0; j < a1.cols; j++)
            c.val[i][j] = a1.val[i][j] + a2.val[i][j];

    return c;
}

The class Matrix represents a matrix, and has a constructor that takes two ints as input (the number of rows and columns in the matrix, respectively), and creates a 2D array of doubles of the appropriate size (named val). This function works as supposed to in that the value for c is correct, but it also appears to destruct a1 and a2. That is, if I write

Matrix c = a + b;

It gives the right result, but a and b are no longer usable, and I get a glibc error at the end of the code claiming I am trying to destruct a and b when they have already been destructed. Why is this?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-31T17:03:37+00:00Added an answer on May 31, 2026 at 5:03 pm

    Your signature is wrong:

    Matrix operator+(Matrix a1, Matrix a2)
    

    it should be

    Matrix operator+(const Matrix& a1, const Matrix& a2)
    

    The reason it appears to destroy a1 and a2 is because, well, it is, since those are temporary copies created in the method scope.

    If the original values are destroyed, you’re probably violating the rule of three. When a1 and a2 are destroyed, the destructor gets called, and you’re probably deleting pointers in the destructor. But since the default copy constructor does only a shallow copy, the copied a2 and a1 will delete the original memory.

    Edit: Since there are split opinions about this, I’ll extend my answer:

    Assume:

    struct A
    {
       int* x;
       A() { x = new int; *x = 1; }
       ~A() { delete x; }
    };
    
    //option 1:
    A operator + (A a1, A a2)
    {
       A a; return a; //whatever, we don't care about the return value
    }
    
    //option 2:
    A operator + (const A& a1, const A& a2)
    {
       A a; return a; //again, we don't really care about the return value
    }
    

    In this first example, the copy constructor is not implemented.

    A copy constructor is generated by the compiler. This copy constructor copies x into the new instance. So if you have:

    A a;
    A b = a;
    assert( a.x == b.x );
    

    Important note that the pointers are the same.

    Calling option 1 will create copies inside operator +, because the values are passed by value:

    A a;
    A b;
    a + b; 
    //will call:
    A operator + (A a1, A a2)
    // a1.x == a.x
    // a2.x == n.x
    

    When operator + exits, it will call delete x on objects a1 and a2, which will delete the memory that is also pointed to by a.x and b.x. That is why you get the memory corruption.

    Calling option 2 however, since no new objects are created because you pass by reference, the memory will not be deleted upon function return.

    However, this isn’t the cleanest way to solve the issue. It solves this issue, but the underlying one is much more important, as Konrad Pointed out, and I have in my original answer (although haven’t given it enough importance, I admit).

    Now, the correct way of solving this is properly following the rule of three. That is, have an implementation for destructor, copy constructor and assignment operator:

    struct A
    {
       int* x;
       A() { x = new int; *x = 1; }
       A(const A& other)  //copy constructor
       {
          x = new int;  // this.x now points to a different memory location than other.x
          *x = other.(*x);  //copy the value though
       }
       A& operator = (const A& other) //assignment operator
       { 
          delete x; //clear the previous memory
          x = new int;     
          *x = other.(*x);  //same as before
       }
       ~A() { delete x; }
    };
    

    With this new code, let’s re-run the problematic option 1 from before:

    A a;
    A b;
    a + b; 
    //will call:
    A operator + (A a1, A a2)
    // a1.x != a.x
    // a2.x != n.x
    

    Because the copies a1 and a2 now point to different memory locations, when they are destroyed, the original memory is intact and the original objects – a and b remain valid.

    Phew! Hope this clears things up.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm probably being stupid, because its Friday afternoon, but I just can't work this
This should be simple an I am probably just being silly but... I need
This question is probably pretty stupid, but I'm new to C# and I'm not
I'm probably just being neurotic, but I regularly find myself in situations in which
This is probably a stupid question, but I just can't figure out how to
This is probably very easy and just I'm being thick - I'm trying to
This will probably be just another unsolved thread but i'll fill in some info
This is probably something really simple but for some reason I just can't seem
This is probably a pretty basic question, but just something that I wanted to
This is probably quite simple, but I just don't know how to do this...

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.