【问题标题】:Destructor causing SegFault C++导致 SegFault C++ 的析构函数
【发布时间】:2020-02-29 06:47:06
【问题描述】:
class Pair {

public:

    int *pa,*pb;


    Pair(int a, int b) 
    {
        pa = new int(a);
        pb = new int(b);
    }

    Pair(const Pair& other) {
        int* pc = new int(*other.pa);
        int* pd = new int(*other.pb);
    }


    ~Pair() {
        delete pa;
        delete pb;
    }

};

在这个程序中,编译器产生了一个分段错误(核心转储),在完全删除析构函数之后,我们可以让程序运行而没有任何错误,那么任何人都可以帮我解决这个问题吗? 即使在参数化构造函数中,我也初始化了指针,编译器会发出警告,指出点 pa 和 pb 未初始化。

【问题讨论】:

  • 这段代码看起来不错。您需要提供一个最小的可重现错误示例(如何使用 Pair 对象)
  • 在复制构造函数中,您不会初始化成员变量(您声明了 2 个新的局部变量 pcpd)。阅读副本,请发布minimal reproducible example,其中应包含足够的代码来重现问题。
  • 您的复制构造函数没有设置当前实例的 pa & pb。它正在泄漏/立即丢弃它分配的内存。您还缺少复制分配运算符。
  • 你在这里做什么? ``` Pair(const Pair& other) { int* pc = new int(other.pa); int pd = new int(*other.pb); } ```

标签: c++ destructor copy-constructor


【解决方案1】:

:你的复制构造函数创建了两个指针,然后将它们泄露出去。它从不设置类的成员变量。

您可能想参考三 / 五 / 等规则,为了清楚起见,delete 默认构造函数不会有什么坏处。

class Pair {
public:
    int *pa, *pb;

    Pair() = delete;
    Pair(int a, int b): pa{new int{a}}, pb{new int{b}} {}
    Pair(const Pair& other): pa{new int{*other.pa}}, pb{new int{*other.pb} {}

    ~Pair(){
        delete pa;
        delete pb;
    }
};

【讨论】:

  • 哎呀。那应该是pa{new int{a}}pb{new int{b}}。定影。它将pa 设置为new int{a},将pb 设置为new int{b}
【解决方案2】:

对于您的复制构造函数,您应该(很可能)这样做:

Pair(const Pair& other) {
    pa = new int(*other.pa);
    pb = new int(*other.pb);
}

这就是你期望复制构造函数做的事情。

使用您的代码,当您在 Pair 对象上调用析构函数时,通过其复制构造函数,您正在尝试删除未初始化的指针。

【讨论】:

    【解决方案3】:

    可能的问题(尽管仅用您当前给出的代码很难判断)是这些行:

    int* pc = new int(*other.pa);
    int* pd = new int(*other.pb);
    

    这重新声明了新的指针pcpd,实际上并没有设置你的成员变量papb。一旦构造函数退出,这些新指针就会超出范围。最好的情况是潜在的内存泄漏,最坏的情况是 deleteing 未初始化的指针——这可能会导致崩溃。

    要修复,您需要实际设置您的成员并删除 int* 关键字:

    pa = new int(*other.pa);
    pb = new int(*other.pb);
    

    【讨论】:

      【解决方案4】:

      考虑使用std::unique_ptr 来管理资源,而不是使用原始指针:

      #include <memory>
      
      class Pair {
      public:
          std::unique_ptr<int> pa, pb;
      
          Pair(int a, int b) 
          {
              pa = std::make_unique<int>(a);
              pb = std::make_unique<int>(b);
          }
      };
      
      int main() {
          Pair p {1, 2};
          return 0;
      }
      

      【讨论】:

      • 虽然是一种可能的解决方案,但这不一定是这里的问题。
      猜你喜欢
      • 2016-10-12
      • 2019-08-25
      • 2012-09-23
      • 2017-03-21
      • 2021-03-14
      • 2012-03-09
      • 2013-04-13
      • 2011-08-18
      • 2013-04-30
      相关资源
      最近更新 更多