Segfault if изменить значение указателя из производного класса - PullRequest
0 голосов
/ 25 октября 2019

Я, к сожалению, не могу правильно описать свою проблему, но:

Когда я пытаюсь изменить значение указателя bar, определенное в базовом классе 'A', из дочернего класса 'B' сметод foo() это дает мне ошибку по умолчанию, потому что строка указателя равна нулю:

#include <iostream>
class A {
    protected:
        virtual void foo() {};
        int* bar;
    public:
        void eval(){
            foo();
            std::cout << *bar;
        }

};

class B : public A {
    void foo() override {
        *bar = 10; //segfault
    }
};

int main(){
    B* foobar = new B();
    foobar->eval();
}

Но, если строка не указатель, а обычная переменная, она работает нормально.

1 Ответ

5 голосов
/ 25 октября 2019

Ваш bar не указывает ни на что, так как он не указывает на int, вы не можете присвоить значение его int (*bar = 10 = segfault). Добавьте конструктор к A, который исправит это:

class A {
protected:
    A() {                       // <- Constructor
        bar = new int(0);
    }
    A(const A& other)           // <- Copy sonstructor
    {
        bar = new int(*other.bar);
    }
    A& operator=(A other)       // Assignment operator
    {
        std::swap(bar, other.bar);
        return *this;
    }
    virtual ~A() {              // <- Destructor
        delete bar;
    }

    virtual void foo() {}
    int* bar = nullptr;
public:
    void eval() {
        foo();
        std::cout << *bar;
    }
};

Тогда весь остальной код будет работать, и eval() напечатает 10, как и предполагалось. Обратите внимание, добавление деструктора для очистки bar позже необходимо для предотвращения утечек памяти.

Редактировать:

Как очень правильно указал MikeCAT, я был оченьслишком поспешный и нарушил правило трех в моем ответе. Если вы делаете динамическое размещение, вам понадобятся и деструктор, и конструктор копирования, и оператор присваивания. Я добавил их в код выше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...