Search code examples
c++memorydouble-free

C++ Why is my program getting the error free(): double free detected in tcache 2 in GDB


So I am having to do this exercise for a course in Udemy and I finished it. But running in on my own machine in GDB I get the error above in the title. I tried checking the values of the pointers for the points prior and after destruction and the values of start behaved strangely on the destructor both of line and copy(both in the scope of main) On the first call to a destructor I couldn't access the values( it prints normally tho) for start and after destruction start->x was zero ( expected) but at the second destructor the value for start->x that was supposed to be three was zero too. But nothing in my code tells me (it might tell someone else) it's supposed to do that. I just can't figure it out

struct Point
{
  int x{ 0 }, y{ 0 };

  Point(){}
  
  Point(const int x, const int y) : x{x}, y{y} {}
};

struct Line
{
  Point *start, *end;
  
  Line(Point* const start, Point* const end)
    : start(start), end(end)
  {
  }

  Line()
  {
  }

  ~Line()
  {
    delete start;
    delete end;
  }

  Line& deep_copy() const 
  {
    Point *cstart=new Point;
    Point *cend=new Point;

    (*cstart)=*start;
    (*cend)=*end;

    static Line copy{cstart, cend};
    return copy;
  }
};
#include <iostream>
using namespace std;

int main (){

    Point *start= new Point(1,2);
    Point *end  = new Point(3,4);
    Line line{start, end}, copy;
    cout << line.start->x <<endl<< line.start->y <<endl<< line.end->x <<endl<< line.end->y <<endl;

    copy = line.deep_copy();

    cout << copy.start->x <<endl<< copy.start->y <<endl<< copy.end->x <<endl<< copy.end->y <<endl;
    return 0;
}

Solution

  • When run, your program will create 3 Line objects:

    • line in main (denoted hereafter by main::line)
    • copy in main (denoted hereafter by main::copy)
    • copy in deep_copy (denoted hereafter by deep_copy::copy)

    Since deep_copy::copy is a static object, it remains in memory after its creation till the end of the program run.

    Correspondingly, your program will have 3 destructor calls (pertaining to the Line struct objects). The first two will be for main::copy and main::line. The third destructor call will be for deep_copy::copy at the end of program run. Note that, the pointers (start and end) for main::copy and deep_copy::copy point to the same location, as the two objects are a copy of each other. Thus, during the third destructor call (meant for deep_copy::copy), the memory pointed to by start and end of deep_copy::copy has already been freed by the previous destructor call for main::copy.

    This leads to the runtime error: free(): double free detected in tcache 2, as your program tries to free a memory location that has already been freed.