Thread: Abnormal program termination

  1. #1
    Registered User Kayoss's Avatar
    Join Date
    Sep 2005
    Location
    California
    Posts
    53

    Abnormal program termination

    This code is from the Deitel book, but will only cout partway before issuing a debug error:

    Code:
    #include <iostream>
    #include <string>
    #include <iomanip>
    #include <vector>
    #include <typeinfo>
    
    using namespace std;
    
    class Employee {
    
    public:
       Employee( const string &, const string &, const string & );
    
       void setFirstName( const string & );
       string getFirstName() const;
    
       void setLastName( const string & );
       string getLastName() const;
    
       void setSocialSecurityNumber( const string & );
       string getSocialSecurityNumber() const;
    
       // pure virtual function makes Employee abstract base class
       virtual double earnings() const = 0; // pre virtual
       virtual void print() const; // virtual
    
    private:
       string firstName;
       string lastName;
       string socialSecurityNumber;
    
    }; // end class Employee
    
    // constructor
    Employee::Employee( const string &first, const string &last,
       const string &SSN )
       : firstName( first ),
          lastName( last ),
          socialSecurityNumber( SSN )
    {} // empty body, end Employee constructor
    
    // return first name
    string Employee::getFirstName() const
    {	
       return firstName;
    } // end function getFirstName
    
    // return last name
    string Employee::getLastName() const
    {
       return lastName;
    } // end function getLastName
    
    // return social security number
    string Employee::getSocialSecurityNumber() const
    {
       return socialSecurityNumber;
    } // end function getSocialSEcurityNumber
    
    // set first name
    void Employee::setFirstName( const string &last )
    {
       lastName = last;
    } // end function setLastName
    
    // set social security number
    void Employee::setSocialSecurityNumber( const string & number )
    {
       socialSecurityNumber = number; // should validate
    } // end function setSocialSEcurityNumber
    
    // print Employee's information
    void Employee::print() const
    {
       cout << getFirstName() << ' ' << getLastName()
    	<< "\nsocial security number: "
    	<< getSocialSecurityNumber() << endl;
    } // end function print
    
    class SalariedEmployee : public Employee {
    
    public:
       SalariedEmployee( const string &, const string &,
    	const string &, double = 0.0 );
    
       void setWeeklySalary( double );
       double getWeeklySalary() const;
    
       virtual double earnings() const;
       virtual void print() const; // "salaried employee: "
    
    private:
       double weeklySalary;
    
    }; // end class SalariedEmployee
    
    SalariedEmployee::SalariedEmployee( const string &first,
       const string &last, const string &socialSecurityNumber, double salary )
       : Employee( first, last, socialSecurityNumber )
    {
       setWeeklySalary( salary );
    } // end SalariedEmployee constructor
    
    // set salaried employee's salary
    void SalariedEmployee::setWeeklySalary( double salary )
    {
       weeklySalary = salary < 0.0 ? 0.0 : salary;
    } // end function setWeeklySalary
    
    // calculate salaried employee's pay
    double SalariedEmployee::earnings() const
    {
       return getWeeklySalary();
    } // end function earnings
    
    // return salaried employee's salary
    double SalariedEmployee::getWeeklySalary() const
    {
       return weeklySalary;
    } // end fucntion getWeeklySalary
    
    // print salaried employee's name
    void SalariedEmployee::print() const
    {
       cout << "\nsalaried employee: ";
       Employee::print(); // code reuse
    } // end function print
    
    class HourlyEmployee : public Employee {
    
    public:
       HourlyEmployee( const string &, const string &,
          const string &, double = 0.0, double = 0.0 );
    
       void setWage( double );
       double getWage() const;
    
       void setHours( double );
       double getHours() const;
    
       virtual double earnings() const;
       virtual void print() const;
    
    private:
       double wage; // wage per hour
       double hours; // hours worked for the week
    }; // end class HourlyEmployee
    
    HourlyEmployee::HourlyEmployee( const string &first,
       const string &last, const string &socialSecurityNumber, double
       hourlyWage, double hoursWorked )
       : Employee( first, last, socialSecurityNumber )
    {
       setWage( hourlyWage );
       setHours( hoursWorked );
    } // end HourlyEmployee constructor
    
    // set hourly employee's wage
    void HourlyEmployee::setWage( double wageAmount )
    {
       wage = wageAmount < 0.0 ? 0.0 : wageAmount;
    } // end function setWage
    
    // set hourly employee's hours worked
    void HourlyEmployee::setHours( double hoursWorked )
    {
       hours = ( hoursWorked >= 0.0 && hoursWorked <= 168.0 ) ?  hoursWorked : 0.0;
    } // end function setHours
    
    // return hours worke3d
    double HourlyEmployee::getHours() const
    {
       return hours;
    } // end function getHours
    
    double HourlyEmployee::getWage() const
    {
       return wage;
    } // end function getWage
    
    // get hourly employee's pay
    double HourlyEmployee::earnings() const
    {
       if ( hours <= 40 ) // no overtime
          return wage * hours;
       else
          return 40 * wage + ( hours - 40 ) * wage * 1.5;
    } // end function earnings
    
    // print hourly employee's information
    void HourlyEmployee::print() const
    {
       cout << "\nhourly employee: ";
       Employee::print(); // code reuse
    } // end function print
    
    class CommissionEmployee : public Employee {
    
    public:
       CommissionEmployee( const string &, const string &, const string &, double = 0.0, double = 0.0 );
    
       void setCommissionRate( double );
       double getCommissionRate() const;
    
       void setGrossSales( double );
       double getGrossSales() const;
    
       virtual double earnings() const;
       virtual void print() const;
    
    private:
       double grossSales; // gross weekly sales
       double commissionRate;  // commission percentage
    };
    
    // CommissionEmployee constructor
    CommissionEmployee::CommissionEmployee( const string &first, const string &last,
       const string &socialSecurityNumber, double grossWeeklySales, double percent )
       : Employee( first, last, socialSecurityNumber )
    {
       setGrossSales( grossWeeklySales );
       setCommissionRate( percent );
    } // end CommissionEmployee constructor
    
    // return commission employee's rate
    double CommissionEmployee::getCommissionRate() const
    {
       return commissionRate;
    } // end function getGrossSales
    
    // return commission employee's gross sales amount
    double CommissionEmployee::getGrossSales() const
    {
       return grossSales;
    } // end function getGrossSales
    
    // set commission employee's weekly base salary
    void CommissionEmployee::setGrossSales( double sales )
    { 
       grossSales = sales < 0.0 ? 0.0 : sales;
    } // end function setGrossSales
    
    // set commission employee's commission
    void CommissionEmployee::setCommissionRate( double rate )
    {
       commissionRate = ( rate > 0.0 && rate < 1.0 ) ? rate : 0.0;
    } // end function setCommissionRate
    
    // calculate commission employee's earnings
    double CommissionEmployee::earnings() const
    {
       return getCommissionRate() * getGrossSales();
    } // end function earnings
    
    // print commission employee's name
    void CommissionEmployee::print() const
    {
       cout << "\ncommission employee: ";
       Employee::print(); // code reuse
    } // end function print
    
    class BasePlusCommissionEmployee : public CommissionEmployee {
    
    public:
       BasePlusCommissionEmployee( const string &, const string &,
    	const string &, double = 0.0, double = 0.0, double = 0.0 );
    
       void setBaseSalary( double );
       double getBaseSalary() const;
    
       virtual double earnings() const;
       virtual void print() const;
    
    private:
       double baseSalary; // base salary per week
    }; // end class BasePlusCommissionEmployee
    
    BasePlusCommissionEmployee::BasePlusCommissionEmployee(
        const string &first, const string &last,
        const string &socialSecurityNumber,
        double grossSalesAmount, double rate,
        double baseSalaryAmount )
        : CommissionEmployee( first, last, socialSecurityNumber,
        grossSalesAmount, rate )
    {
       setBaseSalary( baseSalaryAmount );
    } // end BasePlusCommissionEmployee constructor
    
    // set base-salaried commission employee's wage
    void BasePlusCommissionEmployee::setBaseSalary( double salary )
    {
       baseSalary = salary < 0.0 ? 0.0 : salary;
    } // end function setBaseSalary
    
    // return base-salaried commission employee's base salary
    double BasePlusCommissionEmployee::getBaseSalary() const
    {
       return baseSalary;
    } // end function getBaseSalary
    
    // return base-salaried commission employee's earnings
    double BasePlusCommissionEmployee::earnings() const
    {
       return getBaseSalary() + CommissionEmployee::earnings();
    } // end function earnings
    
    // print base-salaried commission employee's name
    void BasePlusCommissionEmployee::print() const
    {
       cout << "\nbase-salaried commission employee: ";
       Employee::print();
    } // end function print
    
    int main()
    {
       // set floating-oint output formatting
       cout << fixed << setprecision( 2 );
    
       // create vector employee
       vector < Employee * > employees( 4 );
    
       // initialize vector with Employees
       employees[ 0 ] = new SalariedEmployee( "John", "Smith",
    	"111-11-1111", 800.00 );
       employees[ 1 ] = new CommissionEmployee( "Sue", "Jones",
    	"222-22-2222", 10000, .06 );
       employees[ 2 ] = new BasePlusCommissionEmployee( "Bob",
    	"Lewis", "333-33-3333", 300, 5000, .04 );
       employees[ 3 ] = new HourlyEmployee( "Karen", "Price",
    	"444-44-4444", 16.75, 40 );
    
       // generically perocess each element in vector employees
       for ( int i = 0; i < employees.size(); i++ ) {
    
    	// output employee information
    	employees[ i ]->print();
    
    	// downcast pointer
    	BasePlusCommissionEmployee *commissionPtr =
    	dynamic_cast < BasePlusCommissionEmployee * >
    			( employees[ i ] );
    
    	// deteremine whether element points to base-salaried commission
    	// employee
    	if ( commissionPtr != 0 ) {
    	   cout << "old base salary: $"
    	      << commissionPtr->getBaseSalary() << endl;
    	   commissionPtr->setBaseSalary(
    	      1.10 * commissionPtr->getBaseSalary() );
    	   cout << "new base salary with 10% increase is: $"
    		<< commissionPtr->getBaseSalary() << endl;
    	} // end if
    
    	cout << "earned $" << employees[ i ]->earnings() << endl;
       } // end for
    
       // release memory held by vector employees
       for ( int j = 0; j < employees.size(); j++ ) {
    
       // output class name
       cout << "\n deleting object of "
               << typeid( *employees[ j ] ).name();
    
       delete employees[ j ];
    } // end for
    
       cout << endl;
    
       return 0;
    
    } // end main
    It will print
    Code:
    salaried employee: John Smith
    social security number: 111-11-1111
    then gives the following error:
    Code:
    Debug Error!
    abnormal program termination
    (Please retry to debug the application)
    When I retry, the error repeats using MSC++ 6.0, does anyone else get the same error?
    THE redheaded stepchild.

  2. #2
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    From MSVC++ 6.0, hit F10. Once the debugger starts, go to Debug->Exceptions... Select all the exceptions in the list and click Stop Always, then click Change (they might not all update, but that's ok). Hit OK.

    Now hit F5. When the exception occurs, it will take you to the location in the code that caused the error. If it takes you to disassembly, or to some other file that you didn't write, open the Call Stack and double click on the highest function from your file.

  3. #3
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    BTW, the problem might be that you need to turn on RTTI... Did you get this warning:
    Code:
    warning C4541: 'dynamic_cast' used on polymorphic type 'class Employee' with /GR-;
    unpredictable behavior may result
    You should always pay attention to warnings and try to fix them or understand what they mean.

    To turn on RTTI in VC++6.0, go to Project->Settings, C/C++ tab, C++ Language category, and check Enable Run-Time Type Information (RTTI).


    Also, there is a bug in that code that causes undefined behavior. The base class needs a virtual destructor.

  4. #4
    Registered User Kayoss's Avatar
    Join Date
    Sep 2005
    Location
    California
    Posts
    53
    Quote Originally Posted by Daved
    To turn on RTTI in VC++6.0, go to Project->Settings, C/C++ tab, C++ Language category, and check Enable Run-Time Type Information (RTTI).

    The base class needs a virtual destructor.
    These worked for me, thank you very much for your advice!
    THE redheaded stepchild.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 06-23-2006, 07:03 PM
  2. Need help with my program...
    By Noah in forum C Programming
    Replies: 2
    Last Post: 03-11-2006, 07:49 PM
  3. quick termination of program
    By jobolikescake in forum C Programming
    Replies: 7
    Last Post: 01-20-2002, 10:59 PM
  4. abnormal program termination
    By ProLin in forum C++ Programming
    Replies: 2
    Last Post: 01-20-2002, 09:56 PM
  5. My program, anyhelp
    By @licomb in forum C Programming
    Replies: 14
    Last Post: 08-14-2001, 10:04 PM