Деструктор, вызывающий SegFault C ++ - PullRequest
0 голосов
/ 04 ноября 2019
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 не инициализированы.

Ответы [ 4 ]

2 голосов
/ 04 ноября 2019

: ваш конструктор копирования создает два указателя, а затем просто пропускает их. Он никогда не устанавливает переменные-члены класса.

Возможно, вы захотите обратиться к правилу три / пять / и т. Д., И это не помешает 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;
    }
};
1 голос
/ 04 ноября 2019

Вероятная проблема (хотя трудно сказать только с кодом, который вы в данный момент дали) заключается в следующих строках:

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

Это повторно объявляет новые указатели pc и pdи фактически не устанавливает ваши переменные-члены pa и pb. Эти новые указатели выходят из области видимости после выхода из конструктора. В лучшем случае это потенциальная утечка памяти, в худшем - вы delete указатели, которые не были инициализированы, что может стать причиной вашего сбоя. int* ключевые слова:

pa = new int(*other.pa);
pb = new int(*other.pb);
1 голос
/ 04 ноября 2019

Для вашего конструктора копирования вы должны (скорее всего) сделать это:

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

Это делает то, что вы ожидаете от конструктора копирования.

Использование вашего кода, когдаВы вызываете свой деструктор для объекта Pair, сделанного через его конструктор копирования, вы пытаетесь удалить неинициализированные указатели.

0 голосов
/ 04 ноября 2019

Вместо использования необработанных указателей рассмотрите возможность использования 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;
}
...