0

I'm writing a simple program to demonstrate my knowledge of derived classes.

I'm setting different variables of the derived classes, then outputting those variables to the screen and looping numRobots times. However, after outputting the first iteration successfully, the program outputs segmentation fault (core dumped). I can't figure out why.

All the derived classes work when I use them for the first iteration. The program just doesn't loop to the second iteration.

Here's my code:

#include <iostream>
#include <iomanip>
#include "abstractrobot.h"
#include "wrapperrobot.h"
#include "benderrobot.h"
#include "welderrobot.h"
using namespace std;

int main()
{
  cout.setf(ios_base::fixed,ios_base::floatfield);
  cout.precision(2);

  int numRobots;
  int robotType;
  string robotName;

  cin >> numRobots;

  for (int i = 0; i < numRobots; i++)
  {
    cin >> robotType;
    cin >> robotName;

    switch (robotType)
    {
      case 0:
      {
        WrapperRobot a_wrapper(robotName);

        int numHours, numPackages;

        cin >> numHours;
        a_wrapper.set_numHours(numHours);

        cin >> numPackages;
        a_wrapper.set_numPackages(numPackages);

        cout << "#" << i << ": ";
        cout << a_wrapper.getName() << ", " << a_wrapper.getType()
             << " $" << a_wrapper.getPay() << endl;

        break;
      }

      case 1:
      {
        BenderRobot a_bender(robotName);

        int numReg, numExtra, numBends;

        cin >> numReg;
        a_bender.set_numReg(numReg);
        cin >> numExtra;
        a_bender.set_numExtra(numExtra);
        cin >> numBends;
        a_bender.set_numBends(numBends);

        cout << "#" << i << ": ";
        cout << a_bender.getName() << ", " << a_bender.getType()
             << " $" << a_bender.getPay() << endl;

        break;
      }

      case 2:
      {
        WelderRobot a_welder(robotName);

        int numReg, numExtra, numRad;

        cin >> numReg;
        a_welder.set_numReg(numReg);
        cin >> numExtra;
        a_welder.set_numExtra(numExtra);
        cin >> numRad;
        a_welder.set_numRad(numRad);

        cout << "#" << i << ": ";
        cout << a_welder.getName() << ", " << a_welder.getType()
             << " $" << a_welder.getPay() << endl;

      break;
      }

      default:
        cout << "Invalid type" << endl;
    }
cout << "hello" << endl; // tester; the program never outputs this
  }

  return 0;
}

Here's the header file for the robot of type 0:

#ifndef WRAPPERROBOT_H
#define WRAPPERROBOT_H

#include <string>
#include "abstractrobot.h"
using namespace std;

class WrapperRobot : public AbstractRobot
{
  private:
    float numHours;
    float numPackages;

  protected:
    string c_name;

  public:
    const float c_rate = 0.25;
    const float c_bonus = 0.05;
    const string c_type = "Wrapper";

    WrapperRobot(string n) : AbstractRobot(n) {c_name = n;}

    virtual float getPay() const {return ((c_rate * numHours) +
                                     (c_bonus * numPackages));}

    virtual const string& getName() const {return c_name;} 

    virtual const string& getType() const {return c_type;} 

    virtual ~WrapperRobot() {delete this;}

    void set_numHours(int n);
    int get_numHours() {return numHours;}

    void set_numPackages(int n);
    int get_numPackages() {return numPackages;}
};

#endif

wrapperrobot.cpp

#include "wrapperrobot.h"

void WrapperRobot::set_numHours(int n)
{
    numHours = n;
    return;
}

void WrapperRobot::set_numPackages(int n)
{
    numPackages = n;
    return;
}

The abstract class:

#ifndef ABSTRACTROBOT_H
#define ABSTRACTROBOT_H

#include <string>

using namespace std; 

class AbstractRobot
{
    protected:
        string c_name;

    public:  
        AbstractRobot(string n)
        {
            c_name = n;
        }

        virtual float getPay() const = 0;

        virtual const string& getName() const = 0;

        virtual const string& getType() const = 0;

        virtual ~AbstractRobot() {}
};


#endif

Here's my input:

4 0 Unit 10 20

The program outputs: #0: Unit, Wrapper $3.50 Segmentation fault (core dumped)

David Bippes
  • 65
  • 2
  • 4
  • Since you say that the program segfaults after the first iteration, it's likely that the problem is somewhere in the destruction of your robots. You should include the code (at least the header file and destructor body) for your abstract robot and for one of the concrete robots, for which this problem occurs when you choose it on the first iteration. – TerraPass Mar 24 '16 at 00:12
  • @TerraPass I've added them. – David Bippes Mar 24 '16 at 00:23

1 Answers1

1
virtual ~WrapperRobot() {delete this;}

Don't do delete this; from destructor, ever. Destructor is invoked when somebody else delete's your object, or when, as in your case, it's destroyed automatically after being allocated on the stack, once its scope ends. If you don't need to deallocate any memory or free any resources in your destructor, just leave its body empty.

I'm actually surprised that you've got a segfault and not a stack overflow, since delete this; in destructor should trigger an infinite recursion. EDIT: Or at least I was, until I googled this question.

Community
  • 1
  • 1
TerraPass
  • 1,562
  • 11
  • 21