V
V
Vladimir Korshunov2021-10-02 14:10:53
C++ / C#
Vladimir Korshunov, 2021-10-02 14:10:53

How not to call the destructor twice?

I'm doing a binary operator overload -. I am making a queue class. I make the expression c = a - b, where a,b,c are objects of the queue class. I have a function that overloads this operator. An auxiliary object is created inside it, in which the desired difference is stored. If I return this object, then after the end of the function, its destructor will be called, the memory will be cleared, and the result of this will be written to c. Moreover, then the destructor of class c will be called again, and it will clear the same memory again and an error will be thrown. What can be done in such cases? If I use this, then my object a will change, which should not happen. I would like to just write the result to c.

class Queue
{
private:
    struct elem
    {
        elem *next, *prev;
        int info;
    };
    elem *head, *tail;
    int len;
public:
    //конструктор
    Queue(double inf)
    {
        head = new elem;
        tail = new elem;
        len = 1;
        head->info = inf;
    };
    
    Queue()
    {
        head = NULL;
        tail = NULL;
        len = 0;
    }
    //деструктор
    ~Queue()
    {
        elem *n = tail;
        while (tail != NULL)
        {
            n = tail;
            tail = tail->next;
            len--;
            delete n;
            n = NULL;
        }
    };
...
};

Queue operator-(Queue a)
    {
        elem* n1 = head;
        Queue answ;
        //создание копии
        for (int i = 0; i < len; i++)
        {
            answ.enqueue(n1->info);
            n1 = n1->prev;
        }

        ...
 
        return answ;
    }

Answer the question

In order to leave comments, you need to log in

3 answer(s)
V
Vladimir Korshunov, 2021-10-03
@GashhLab

Added an assignment operator, into which the object that was being overwritten was passed. It turned out that the destructor of this very object is called after the assignment operator, so I just wrote everything into the object for which the assignment operator was called (already with different addresses), but the old object was destroyed after that.

D
Denis Zagaevsky, 2021-10-02
@zagayevskiy

The problem here is not the destructor, but the constructors. You need to implement copy and move constructors, otherwise you will constantly copy pointers from instance to instance, and when you destroy them, you will end up with such bastards as you described. Now the default copy constructor works when passing arguments and when returning from a function. Locally, this can be treated with references, but globally - only the correct constructors.

M
maaGames, 2021-10-02
@maaGames

In "operator -" you need to pass a constant reference, not by value.
Option 1: Use the move constructor. There is no 100% guarantee, but in some cases a copy will not be made.
Option 2. Instead of an operator, use a function that takes a reference to the result as an argument. Then there will be no temporary object at all, you will immediately write data to the resulting queue.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question