ohmygoddess ohmygoddess - 3 months ago 24
C++ Question

C++ derived class call base class method give segmentation fault

Suppose I have a base class and derived class similar to following:

#include "Sprite.h"
class Base{
private:
int X; //location
Sprite* sprite;
public:
Base(Sprite* sprite){
sprite = new Sprite(some parameter);
}
int getLocation(){
return X;
}
int getWidth(){
return sprite->getWidth();
}
}


class Derived : public Base{
private:
Sprite* sprite; // here I have to redefine it in constructor
public:
Derived(Sprite* sprite); // it's different that base constructor
{ sprite = new Sprite(some parameter);
sprite->setPriperty(some parameter);
}
}


When I called Derived::getLocation() from other place, there is no error. But when I called the Derived::getWidth(), it gave me segmentation fault. I have to copy the same code from base class(i.e copy the code of the getWidth into the derived class) in order to avoid the fault. I also tried to use "using Base::getWidth;", but still, gave me segmentation fault. It seems that if the base class method contains pointers t

Answer

So first of all - what is a segmentation fault? It's something simmilar to a NullPointerException in Java or a NullReferenceException in C#. It happens when you try to access non allocated memory.

Why is this happening? You forgot to allocate memory for the sprite pointer, so it's pointing at some not precised memory chunk. You should initialize it in your constructor by using the new operator like this:

Base::Base(Sprite* sprite) {
    this->sprite = new Sprite(sprite);
}

If you like to live dangerously you could also do the following:

Base::Base(Sprite* sprite) {
    this->sprite = sprite;
}

But it's not safe, because the sprite could be allocated on the stack, so code like this could wreck havoc to your program causing undefined behavior:

Base * getBase() {
    Sprite sprite;
    //some code operating on sprite
    return new Base(&sprite);
}

It's hazardous, because after exiting the getBase function there is no sprite anymore in the memory.

Update:

So basically what I concluded from you comments is that you don't call the proper constructor of your Base class. Your Derived constructor should look like this:

Derived(Sprite* sprite): Base(sprite) {
   ...
}

If you don't do this you do not set the value of sprite for your base class. Your sprite field of your derived class is just shadowing the sprite field of your Base class. It's like:

int i = 0;
void fun() {
    int i = 20;
}

In the example the global i did not change, because it was shadowed.

Your code works after duplicating the getWidth() method in the Derived class, because it was accessing then the sprite field of your Derived class. To be clear - without overriding the method getWidth() is accessing the sprite field of the Base class, when you override it it accesses the field of the Derived class.

Comments