I write a vector. When overloading + operation, problems arise.

template<typename T> Vector<T> Vector<T>::operator +(Vector<T>& v) { Vector<T>* v1 = new Vector<T>(_size + v._size,"temp_v1"); for(int i=0;i<_size;i++) { v1->at(i) = ptr[i]; } for(int i=_size;i<v1->_size;i++) { v1->at(i)=v.at(i-_size); } return *v1; } 

With Vector<T>* v1 = new Vector<T>(_size + v._size,"temp_v1"); In my understanding, memory is simply allocated for n elements of type Vector<T> , but after return *v1; for it the destructor is called.

 int main() { Vector<int> v(0,"v"),v1(0,"v1"); v.push_back(0); v1.push_back(1); Vector<int> v2; v2 = v+v1; std::cout<<v2<<std::endl; } 

Accordingly, as far as I understood, in v2 refers to 2 elements of the cleared memory block and, when calling the destructor for v2 , the program crashes, referring to double clearing of memory.

Please explain why this is happening and how to fix it.

    2 answers 2

    No need to create an object on the heap. Get a normal local variable:

     Vector<T> v1(_size + v._size, "temp_v1"); // необходимые манипуляции return v1; 

    With this, of course, the minimum necessary functions should be implemented. Those. should be familiar with the "rule of three" . Then, most likely, all your double removal errors will go away.

    PS In modern C ++, the “rule of three” expands to the “rule of five”, and alternatively it can be replaced with the “rule of zero”. More information can be found here .

    • “The rule of three” is obsolete, now it is “the rule of five or zero” - ixSci
    • one
      @ixSci agree. But I'm not sure that newbies need to be loaded immediately about moving. Especially when there is no c++11 tag. - αλεχολυτ
    • It seems to me that in the 16th year, C ++ (labels) should be understood as C ++ 14, unless otherwise indicated. - ixSci
    • @ixSci I would gladly agree, but unfortunately, there are not so many educational materials on modern c ++ in Russian. And newbies like TS are also trained in c ++ 03 language versions of the language in 90% of cases, even if their current compiler supports a newer standard. - αλεχολυτ
    • can then indicate in parentheses that for modern C ++ you can still use another rule? I googled, like on the same habr there is a description of the "rule of zero". It may not be useful to the author, but it will be useful to others who get to this page - ixSci

    See, you created a Vector in dynamic memory. He himself quietly hanging. You return a *v - link to it. When returning from a function, a copying assignment is invoked (by the way, it is a copying assignment, because you are returning an lvalue reference, not an rvalue). Everything. Delete your dynamic object to no one - why would? The pointer as a variable with a local retention time will be deleted (respectively, it has a lost object in memory and its leakage), but an object in dynamic memory will not.

    As you are advised, make the returned vector a local variable - also the possibility of optimizing RVO is obtained.

    I don’t see a double release in the above code , but how and what is being done in the rest of the implementation is unknown. Here you only see a memory leak. not bad if you provide a minimal reproducing example ...

    And yet - do not shuffle the indices from three objects so hopelessly, also with very similar names - you will break your eyes by going over :)

    • Thank you very much! I solved the problem, it was just the "rule of three" that the previous speaker mentioned. - sm4ll_3gg