导致SegFault C++的析构函数

Destructor causing SegFault C++

本文关键字:析构函数 C++ SegFault 导致      更新时间:2023-10-16
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没有初始化。

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

您可能想参考3/five/etc规则,为了清楚起见,默认构造函数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;
}
};

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

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

这是你所期望的复制构造函数所做的

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

可能的问题(尽管仅凭您当前给出的代码很难判断(是以下几行:

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

这重新声明了新的指针pcpd,而实际上并没有设置成员变量papb。一旦构造函数退出,这些新指针就会超出作用域。往好里说,这是一个潜在的内存泄漏,往坏里说,你是未初始化的delete指针,这可能会导致崩溃。

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

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

不要使用原始指针,而是考虑使用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;
}