2

Every time I run my code. The terminal says "Segment fault". (I'm new to c++ so maybe you could help me improving my code) I have a base class called "Animal" and a "Dog" and a "Cat" class. I wan't to run "doSmth". In the main I created Cat* and Dog* both Pointer. I use CodeBlocks and my Operating System is Ubuntu 16.04.

#include <iostream>

#ifndef ANIMAL_H
#define ANIMAL_H

class Cat;
class Dog;

class Animal
{
    public:
        Animal();
        virtual ~Animal();

        virtual void doSmth();

    protected:

    private:
};

#endif

#ifndef CAT_H
#define CAT_H

class Cat : public Animal
{
    public:
        Cat();
        virtual ~Cat();

        void doSmth()
        {
            std::cout << "Miau" << std::endl;
        }

    protected:

    private:
};

#endif

#ifndef DOG_H
#define DOG_H

class Dog : public Animal
{
    public:
        Dog();
        virtual ~Dog();

        void doSmth()
        {enter code here
            std::cout << "Wuff" << std::endl;
        }

    protected:

    private:

};

#endif

int main()
{
    Dog* d;
    Cat* c;

    d->doSmth();
    c->doSmth();

    return 0;
}
DanielFvM
  • 45
  • 3
  • 3
    You never initialized `Dog* d;` or `Cat* c;`! –  Feb 03 '18 at 21:08
  • 2
    Not related to your segfault. Consider add `override` when you override a virtual function. http://en.cppreference.com/w/cpp/language/override – llllllllll Feb 03 '18 at 21:11
  • Stripping away most of the cruft, I'm nearly certain what you're trying to do is [**this**](https://ideone.com/edVHGk). At least that is what it would seem. – WhozCraig Feb 03 '18 at 21:21
  • 2
    Most compilers can catch this sort of error these days. Don't ignore the warnings. They often contain important information about how your program will screw up. – user4581301 Feb 03 '18 at 21:21
  • 1
    You don't need to dynamically allocate variables. Use pointers only when necessary. (BTW, you never allocate memory for your critters, you only declare pointers that point *somewhere* or *anywhere* but not allocated memory). – Thomas Matthews Feb 03 '18 at 21:39

2 Answers2

3

The reason you are getting a segmentation fault is because you have not allocated memory for either d, or c, and are trying to access uninitialized data. Change the two declaration lines to:

Dog* d = new Dog{};
Cat* c = new Cat{};

The new operator allocates memory for each of these two classes, although it isn't the only way to do so. Also as a recommendation, I would avoid using pointers here since you don't need them.

On a side note, when overriding virtual functions, one should use the override keyword. (In >C++11)

Arnav Borborah
  • 11,357
  • 8
  • 43
  • 88
  • Just to add to this, since you mention you are new to C++: `override` will only work if your compiler supports C++11 *and* if you have enabled it when compiling. If you use Ubuntu 16.04, the default `g++` compiler should be fine for C++11, but check [this](https://stackoverflow.com/questions/18174988/how-can-i-add-c11-support-to-codeblocks-compiler) to see how you can activate the C++11 option in CodeBlocks – BobMorane Feb 04 '18 at 01:01
  • It is unnecessary to initialise the pointers using operator `new`. It IS necessary to initialise them so they point at valid objects that exist as long as needed. – Peter Feb 04 '18 at 01:33
  • @Peter my answer was only limited to the scope of this question. – Arnav Borborah Feb 04 '18 at 14:23
0

You need to create objects before you use them.

If you are not accessing either object through a pointer to base class, there is no point in having virtual methods. So in this case, you may want your pointers to be Animal *.

Also, since you are now allocating memory for your objects, you should release it by using delete[].

Animal *d = new Dog;
Animal *c = new Cat;

d->doSmth();
c->doSmth();

delete[] c;
delete[] d;

You will also have to implement Dog::Dog(), Dog::~Dog(), Cat::Cat(), Cat::~Cat(), Animal::Animal(), Animal::~Animal() and Animal::doSmth() if you didn't already.

Sid S
  • 6,037
  • 2
  • 18
  • 24