-5

I'm a bit new to object oriented programming in c++ and I've been trying to overload subtraction(-) operator in c++ for a Complex class I created. It is working fine except my program is terminating abnormally.
Below is what I've been trying to do:

#include<iostream>
#include<cstdlib>
class Complex{
    //Data-members
private:
    int re, im;

    //methods
public:
    //Constructor
    Complex(){ /*default Constructor*/ }
    Complex(const int& re_, const int& im_):re(re_), im(im_){}
    //Subtraction(-) operator overloading
    Complex operator-(const Complex& op)
    {
        Complex res(this->re - op.re, this->im - op.im);
        return res;
    }
    //get-set methods for re
    int getReal(){ return re; }
    void setReal(const int& re){ this->re = re; }
    //get-set methods for im
    int getImaginary(){ return im; }
    void setImaginary(const int& im){ this->im = im; }
    //Destructor
    ~Complex(){ free(this); }
};

int main()
{
    Complex a(2, 3), b(3, 5);
    Complex d = a - b;
    std::cout<<"d.re = "<<d.getReal()<<" d.im = "<<d.getImaginary()<<"\n";
    return 0;
}

Can anyone please explain the cause of error.

Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
user9999486
  • 61
  • 1
  • 1
  • 6
  • What `free(this);` is supposed to do? It's unnecessary and causes the error. – HolyBlackCat Nov 14 '18 at 11:55
  • Also, why pass `const int&` instead of a plain `int`? – HolyBlackCat Nov 14 '18 at 11:56
  • 1
    Remove the `free(this)` from the destructor. Calling `free()` with an argument that was not returned by `malloc()` (or related functions, like `calloc()` or `realloc()`) gives undefined behaviour. There is nothing in your code returned by `malloc()`, and doesn't need to be. – Peter Nov 14 '18 at 11:57
  • See also *rule of three* [here](https://stackoverflow.com/a/34740363/509868) – anatolyg Nov 14 '18 at 11:58
  • 1
    @anatolyg - rule of zero is more applicable here. The class doesn't explicitly manage any resource, compiler-supplied default implementations of copy constructor, assignment operator, and destructor are fine. – Peter Nov 14 '18 at 12:00
  • @HolyBlackCat using const int& copies reference and makes variable read only. Hence, consuming less memory and avoiding any change to the variable – user9999486 Nov 14 '18 at 12:03
  • @user9999486 "_Hence, consuming less memory_" Please show me example of system, where it would consume less memory. I, personally, cannot think of the use cases where it would consume less memory, while, simultaneously, I can think of cases, where it consumes more memory (64-bit systems, having 32-bit `int`s). 2) "_and avoiding any change to the variable_" Since the value would be passed by value, any changes you do, would be local to the function. Even if you want to disallow that, `const int` would accomplish the same. – Algirdas Preidžius Nov 14 '18 at 12:35

1 Answers1

4

Never ever do free(this), least of all in the destructor. The memory for the objects will be free'd outside of the destructor, either by the compiler generated code or by the user doing delete or delete[].

In fact this is the cause of your problem, as the objects created never were allocated with malloc.

The proper solution in this case is to not only remove the free call, but the whole destructor, since it's not needed for this class.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • using delete is also terminating the program abnormally. – user9999486 Nov 14 '18 at 11:59
  • @user9999486 `delete` must match a `new`, a `delete[]` must match a `new[]`. Nowhere in your code do you use `new`, so there shouldn't be any `delete`. As I said, it will be done automatically by the compiler since it is the compiler that allocates the objects. – Some programmer dude Nov 14 '18 at 12:05
  • @user9999486 No, not in this example anyway. – Some programmer dude Nov 14 '18 at 12:08
  • how do we know that we need to add an explicit destructor in a class – user9999486 Nov 14 '18 at 12:09
  • @user9999486 If your class obtain a resource of any kind, then you need to release it in the destructor. Lets say your constructor allocates memory (explicitly using `new`) then that memory must be deallocated, typically in a destructor. – Some programmer dude Nov 14 '18 at 12:11
  • @user9999486 "_how do we know that we need to add an explicit destructor in a class_" Example class, where one would need destructor: `class A {int* p; A (): p (new int) {} ~A() {delete p;}};` Note: `p` might be resource of any kind, which might need to be freed. – Algirdas Preidžius Nov 14 '18 at 12:37