C++ 为什么我的程序得到错误 free(): double free detection in tcache 2 in GDB

问题描述

所以我必须为 Udemy 的一门课程做这个练习,我完成了它。但是在我自己的 GDB 机器上运行时,我在标题中遇到了上面的错误。我尝试检查销毁前后点的指针值,并且 start 的值在 line 和 copy 的析构函数上表现得很奇怪(都在 main 的范围内)在第一次调用析构函数时我无法访问开始和销毁后的值(它通常打印) start->x 为零(预期)但在第二个析构函数中, start->x 的值本应为 3 也为零。但是我的代码中没有任何内容告诉我(它可能会告诉其他人)它应该这样做。我就是想不通

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;
}

解决方法

运行时,您的程序将创建 3 Line 个对象:

  • line 在 main(以下用 main::line 表示)
  • copy 在 main(以下用 main::copy 表示)
  • copy in deep_copy(以下用 deep_copy::copy 表示)

由于 deep_copy::copy 是一个静态对象,它在创建后一直保留在内存中,直到程序运行结束。

相应地,您的程序将有 3 次析构函数调用(与 Line 结构对象有关)。前两个将用于 main::copymain::line。第三个析构函数调用将在程序运行结束时调用 deep_copy::copy。请注意,startend 的指针(main::copydeep_copy::copy)指向相同的位置,因为这两个对象是彼此的副本。因此,在第三次析构函数调用期间(用于 deep_copy::copy),startenddeep_copy::copy 所指向的内存已经被 main::copy 的前一个析构函数调用释放了{1}}。

这会导致运行时错误:free(): double free detected in tcache 2,因为您的程序试图释放已被释放的内存位置。