itslayer
itslayer

Reputation: 74

Segfault if change the pointer value from a derived class

I, unfortunately, can't describe my problem properly, but:

When I am trying to change a pointer value bar defined in base class 'A' from a child class 'B' with method foo() it gives me a segfault, because the pointer bar is null:

#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();
}

But, if the bar is not a pointer, but a normal variable it works fine.

Upvotes: 0

Views: 75

Answers (1)

Frodyne
Frodyne

Reputation: 3973

Your bar is not pointing to anything, so as it does not point at an int you cannot assign a value to its int (*bar = 10 = segfault). Add a constructor to A that fixes that:

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

Then the rest of your code works, and eval() prints 10 as intended. Note, adding a destructor to clean up bar later is needed to prevent memory leaks.

Edit:

As very correctly pointed out by MikeCAT, I was much too hasty and violated the Rule of three in my answer. If you do dynamic allocation you will want both a destructor, a copy constructor, and an assignment operator. I have added those to the code above.

Upvotes: 5

Related Questions