GIDForums  

Go Back   GIDForums > Computer Programming Forums > C++ Forum
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
 
Thread Tools Search this Thread Rate Thread
  #1  
Old 29-Nov-2005, 14:07
SergeDrago's Avatar
SergeDrago SergeDrago is offline
New Member
 
Join Date: Nov 2005
Location: Here
Posts: 6
SergeDrago is on a distinguished road

Another Segmentation Fault Problem


Hello again everybody. Today, my problem is getting a comparisons program to work with Rationals, or fractions for those that don't know. My teacher gave us a test program that would check to see if the program we wrote would work the way he wanted it to. However, when I go to use the program it does the first check, if 1/4 is less than 1/3, says segmentation fault and quits.

The program I wrote is as follows:
CPP / C++ / C Code:
#include <iostream>
using namespace std;
#include "Rational.h"

// the setNumerator function sets the numerator value for the object.

void Rational::setNumerator (int numer)
{
        numeratorValue = numer;
}

// setDenominator is responsible for changing the denominatorValue data
// member.  It does some basic error checking to make sure we don.t try
// to set a 0 as the denominator. Our solution to this is to set the
// denom to 1 after outputting an error message

void Rational::setDenominator (int denom)
{

        if (denom != 0)
        {
                denominatorValue = denom;
        }
        else
        {
                cerr << "Illegal denominator.  Using 1 instead" << endl;
                denominatorValue = 1;
        }

        return;
}

// specific constructor, called when one or two arguments are given
// in object instantiation.  Sets rational to appropriate value

Rational::Rational (int numer, int denom)
{
        setNumerator(numer);
        setDenominator(denom);
        reduce();
}

// getNumerator and getDenominator are simple, private inspector
// member functions that return the values of the numerator and
// denominator for our object.

int Rational::getNumerator() const
{
        return numeratorValue;
}

int Rational::getDenominator() const
{
        return denominatorValue;
}

// add() performs addition of two Rational objects.  One object
// is doing the addition, the other object (the argument) is being
// added.  This function creates a very (very!) temporary third
// Rational object as it.s setting itself up to return a value.  It
// returns the newly created Rational object.  This is one of
// the few times you see a constructor called explicitly.

Rational Rational::add (const Rational &r) const
{
        int a = getNumerator();
        int b = getDenominator();
        int c = r.getNumerator();
        int d = r.getDenominator();
        Rational result(a*d + b*c, b*d);
        return result;
}

// multiply() performs multiplying two Rational objects.  One object
// is doing the multiplying, the other object (the argument) is being
// multiplied.  This function creates a very (very!) temporary third
// Rational object as it.s setting itself up to return a value.  It
// returns the newly created Rational object.  This is one of
// the few times you see a constructor called explicitly.

Rational Rational::multiply (const Rational &r) const
{
        int a = getNumerator();
        int b = getDenominator();
        int c = r.getNumerator();
        int d = r.getDenominator();
        Rational result(a*c, b*d);
        return result;
}

// insert() takes an ostream as the only argument.  An ostream
// is an output stream, like cout.  by making this an argument, you
// could output Rational numbers to files or other devices or streams.

void Rational::insert (ostream &streamout) const
{
        streamout << getNumerator() << "/" << getDenominator();
        return;
}

// extract() takes an istream as the only argument.  An istream

// is an input stream, like cin.  by making this an argument, you
// could input Rational numbers from files or other devices or
// streams.

void Rational::extract (istream &streamin)
{
        int numer;
        int denom;
        char slash;
        streamin >> numer >> slash >> denom;
        setNumerator(numer);
        setDenominator(denom);
        reduce();
        return;
}

// Here we implement the + operator.  all this "function" does is end
// up calling the add() behavior of the rational number class.
// by overloading the operator, we are providing the .natural
// interface. for the object that we are looking for to make working
// with Rational objects intuitive.

Rational operator+ (const Rational &left, const Rational &right)
{
        return left.add(right);
}

// and here is the implementation for the * operator.  We simply end up
// calling the multiply() behavior of a rational object.

Rational operator* (const Rational &left, const Rational &right)
{
        return left.multiply(right);
}

// here is the implementation for the << operator.  We simply end
// up calling the insert() behavior of a rational object.  Because
// of the "nature of output" in C++ (to be explained in more detail in 1620)
// we need to return the ostream out of the function.  This is
// a critical step in overloading the << operator.

ostream& operator<< (ostream &output, const Rational &rat)
{
        rat.insert(output);
        return output;
}

// similar stuff for >> operator.

istream& operator>> (istream &input, Rational &rat)
// is an input stream, like cin.  by making this an argument, you
// could input Rational numbers from files or other devices or
// streams.

void Rational::extract (istream &streamin)
{
        int numer;
        int denom;
        char slash;
        streamin >> numer >> slash >> denom;
        setNumerator(numer);
        setDenominator(denom);
        reduce();
        return;
}

// Here we implement the + operator.  all this "function" does is end
// up calling the add() behavior of the rational number class.
// by overloading the operator, we are providing the .natural
// interface. for the object that we are looking for to make working
// with Rational objects intuitive.

Rational operator+ (const Rational &left, const Rational &right)
{
        return left.add(right);
}

// and here is the implementation for the * operator.  We simply end up
// calling the multiply() behavior of a rational object.

Rational operator* (const Rational &left, const Rational &right)
{
        return left.multiply(right);
}

ostream& operator<< (ostream &output, const Rational &rat)
{
        rat.insert(output);
        return output;
}


istream& operator>> (istream &input, Rational &rat)
{
  rat.extract(input);
  return input;
}

/* This is all stuff he wrote with the excpetion of reduce() parts.  Below is what I wrote.
*/


Rational operator- (const Rational &left, const Rational &right)
{
 return left.subtract(right);
}

Rational operator/ (const Rational &left, const Rational &right)
{
 return left.divide(right);
}

bool operator< (const Rational &left, const Rational &right)
{
 return left.lessThan(right);
}

bool operator<= (const Rational &left, const Rational &right)
{
 return left.lessThanEqual(right);
}

bool operator> (const Rational &left, const Rational &right)
{
 return left.greaterThan(right);
}

bool operator>= (const Rational &left, const Rational &right)
{
 return left.greaterThanEqual(right);
}

bool operator== (const Rational &left, const Rational &right)
{
 return left.equalTo(right);
}

bool operator!= (const Rational &left, const Rational &right)
{
 return left.notEqualTo(right);
}

Rational Rational::subtract (const Rational &r) const
{
        int a = getNumerator();
        int b = getDenominator();
        int c = r.getNumerator();
        int d = r.getDenominator();
        Rational result(a*d - b*c, b*d);
        return result;
}

Rational Rational::divide (const Rational &r) const
{
        int a = getNumerator();
        int b = getDenominator();
        int c = r.getNumerator();
        int d = r.getDenominator();
        Rational result(a*d, b*c);
        return result;
}

bool Rational::lessThan (const Rational &r) const
{
 int a = getNumerator();
 int b = getDenominator();
 int c = r.getNumerator();
 int d = r.getDenominator();
 if (Rational(a,b) < Rational(c,d))
  return true;
 else
  return false;
}

bool Rational::lessThanEqual (const Rational &r) const
{
 int a = getNumerator();
 int b = getDenominator();
 int c = r.getNumerator();
 int d = r.getDenominator();
 if (Rational(a,b) <= Rational(c,d))
  return true;
 else
  return false;
}

bool Rational::greaterThan (const Rational &r) const
{
 int a = getNumerator();
 int b = getDenominator();
 int c = r.getNumerator();
 int d = r.getDenominator();
 if (Rational(a,b) > Rational(c,d))
  return true;
 else
  return false;
}

bool Rational::greaterThanEqual (const Rational &r) const
{
 int a = getNumerator();
 int b = getDenominator();
 int c = r.getNumerator();
 int d = r.getDenominator();
 if (Rational(a,b) >= Rational(c,d))
  return true;
 else
  return false;
}

bool Rational::equalTo (const Rational &r) const
{
 int a = getNumerator();
 int b = getDenominator();
 int c = r.getNumerator();
 int d = r.getDenominator();
 if (Rational(a,b) == Rational(c,d))
  return true;
 else
  return false;
}

bool Rational::notEqualTo (const Rational &r) const
{
 int a = getNumerator();
 int b = getDenominator();
 int c = r.getNumerator();
 int d = r.getDenominator();
 if (Rational(a,b) != Rational(c,d))
  return true;
 else
  return false;
}

void Rational::reduce()
{
 int a = numeratorValue;
 int b = denominatorValue;
 int c = 1;
 for ( int counter = 1; counter <= a; counter++ )
  if ( a % counter == 0 && b % counter == 0 )
   c = counter;

 numeratorValue = a/c;
 denominatorValue = b/c;
 return;
}


If you noticed, the program called for a class file and that will follow this.

Rational.h
CPP / C++ / C Code:
#ifndef RATIONAL_H
#define RATIONAL_H
#include <iostream>
using namespace std;

class Rational
{
    public:
        Rational (int num = 0, int den = 1);
        Rational add (const Rational &r) const;
        Rational multiply (const Rational &r) const;
        void insert (ostream &output) const;
        void extract (istream &input);

        // These are new and must be implemented
        Rational subtract (const Rational &r) const;
        Rational divide (const Rational &r) const;
        bool lessThan (const Rational &r) const;
        bool lessThanEqual (const Rational &r) const;
        bool greaterThan (const Rational &r) const;
        bool greaterThanEqual (const Rational &r) const;
        bool equalTo (const Rational &r) const;
        bool notEqualTo (const Rational &r) const;

    private:
        int getNumerator() const;
        int getDenominator() const;
        void setNumerator (int numer);
        void setDenominator (int denom);

        // Reduce is new and must be implemented
        void reduce();

        int numeratorValue;
        int denominatorValue;
};

// Here, we prototype the overloaded operators.  All but the last four are new
// and must be implemented.  The operator<->member function relationship should
// be obvious (i.e., operator<= should be implemented to call the lessThanEqual
// member function).

Rational operator- (const Rational &left, const Rational &right);
Rational operator/ (const Rational &left, const Rational &right);
bool operator<  (const Rational &left, const Rational &right);
bool operator<= (const Rational &left, const Rational &right);
bool operator>  (const Rational &left, const Rational &right);
bool operator>= (const Rational &left, const Rational &right);
bool operator== (const Rational &left, const Rational &right);
bool operator!= (const Rational &left, const Rational &right);

Rational operator+ (const Rational &left, const Rational &right);
Rational operator* (const Rational &left, const Rational &right);
ostream& operator<< (ostream &streamout, const Rational &s);
istream& operator>> (istream &streamin, Rational &r);

#endif


And finally, here is the test program that the teacher gave us.

rattest.cpp
CPP / C++ / C Code:
#include <iostream>
using namespace std;

#include "Rational.h"

void printHeader (const Rational &r, const Rational &l, const char * op);

int main ()
{

        Rational  first(1,4);
        Rational second(1,3);

        /*************************************************************************
         *************************************************************************/

        printHeader(first,second,"<");

        if (first < second)
        {
                cout << "This is true.  This test was correct." << endl;
        }
        else
        {
                cout << "This test failed." << endl;
        }

        /*************************************************************************
         *************************************************************************/

        printHeader(first,second,"<=");

        if (first <= second)
        {
                cout << "This is true.  This test was correct." << endl;
        }
        else
        {
                cout << "This test failed." << endl;
        }

        /*************************************************************************
         *************************************************************************/

        printHeader(first,second,">");

        if (first > second)
        {
                cout << "This test failed." << endl;
        }
        else
        {
                cout << "This is false.  This test was correct." << endl;
        }

        /*************************************************************************
         *************************************************************************/

        printHeader(first,second,">=");

        if (first >= second)
        {
                cout << "This test failed." << endl;
        }
        else
        {
                cout << "This is false.  This test was correct." << endl;
        }

        /*************************************************************************
         *************************************************************************/

        printHeader(first,second,"==");

        if (first == second)
        {
                cout << "This test failed." << endl;
        }
        else
        {
                cout << "This is false.  This test was correct." << endl;
        }

        /*************************************************************************
         *************************************************************************/

        printHeader(first,second,"!=");

        if (first != second)
        {
                cout << "This is true.  This test was correct." << endl;
        }
        else
        {
                cout << "This test failed." << endl;
        }

        /*************************************************************************
         *************************************************************************/

        printHeader(first,second,"+");
        cout << "\tnote: result should be 7/12" << endl;
        cout << "\tYour result: " << first + second << endl << endl;

        /*************************************************************************
         *************************************************************************/

        printHeader(first,second,"-");
        cout << "\tnote: result should be -1/12" << endl;
        cout << "\tYour result: " << first - second << endl << endl;

        /*************************************************************************
         *************************************************************************/

        printHeader(first,second,"*");
        cout << "\tnote: result should be 1/12" << endl;
        cout << "\tYour result: " << first * second << endl << endl;

        /*************************************************************************
         *************************************************************************/

        printHeader(first,second,"/");
        cout << "\tnote: result should be 3/4" << endl;
        cout << "\tYour result: " << first / second << endl << endl;

        /*************************************************************************
         *************************************************************************/

        Rational testReduce (65,165);

        cout << endl << "=============================================================================" << endl << endl;
        cout << "Now testing reduction of 65/165.  Should be 13/33." << endl;

        cout << endl << "\tYour result: " << testReduce << endl;
        cout << endl;

        /*************************************************************************
         *************************************************************************/

        Rational testReduce2 (165,65);

        cout << endl << "=============================================================================" << endl << endl;
        cout << "Now testing reduction of 165/65.  Should be 33/13." << endl;

        cout << endl << "\tYour result: " << testReduce2 << endl;
        cout << endl;

        /*************************************************************************
         *************************************************************************/

        Rational testReduce3 (17,17);

        cout << endl << "=============================================================================" << endl << endl;
        cout << "Now testing reduction of 17/17.  Should be 1/1." << endl;

        cout << endl << "\tYour result: " << testReduce3 << endl;
        cout << endl;

        /*************************************************************************
         *************************************************************************/

        Rational tester4;

        cout << endl << "=============================================================================" << endl << endl;
        cout << "Now testing input.  Enter 8/6 when prompted." << endl;
        cout << endl << "Enter 8/6 now: " << flush;
        cin >> tester4;
        cout << endl << "\tYour Rational number is: " << tester4 << endl;
        cout << endl << "\tThe output should be 4/3 since it should reduce.";

        cout << endl << endl;
        cout << endl << "NOTE: If that scrolled by too quickly, you will want to scroll up to see if all of your functions work correctly.\n\n";
        return 0;
}


/****************************************************************************
 ****************************************************************************/

void printHeader (const Rational &r, const Rational &l, const char * op)
{
        cout << endl << "=============================================================================" << endl << endl;
        cout << "Now testing the " << op << " operator:" << endl << endl;
        cout << "\tTesting " << r << " " << op << " " << l << endl << endl;
}


If that 's not enough to keep people busy for days then I don't know what is. For what I think is wrong is how the printHeader function is running but I was never any good at programming.

I'll be looking at the code for a good while and trying to muddle through it. Any help would be appriciated.
  #2  
Old 29-Nov-2005, 15:54
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 4,703
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold

Re: Another Segmentation Fault Problem


Quote:
Originally Posted by SergeDrago
Hello again everybody. Today, my problem is getting a comparisons program to work with Rationals, or fractions for those that don't know. My teacher gave us a test program that would check to see if the program we wrote would work the way he wanted it to. However, when I go to use the program it does the first check, if 1/4 is less than 1/3, says segmentation fault and quits.

Since the code for the overloaded "<" operator fails the first test, look at the code:

CPP / C++ / C Code:
bool operator< (const Rational &left, const Rational &right)
{
 return left.lessThan(right);
}

This calls the member function lessThan, so look at its code:

CPP / C++ / C Code:
bool Rational::lessThan (const Rational &r) const
{
 int a = getNumerator();
 int b = getDenominator();
 int c = r.getNumerator();
 int d = r.getDenominator();
 if (Rational(a,b) < Rational(c,d))
  return true;
 else
  return false;
}
This calls the overloaded "<" operator.

See the problem? No? Then try this:

CPP / C++ / C Code:
bool Rational::lessThan (const Rational &r) const
{
  int a = getNumerator();
  int b = getDenominator();
  int c = r.getNumerator();
  int d = r.getDenominator();
  cout << "In lessThan" << endl;
  cout << "a = " << a << ", b = " << b << ", c = " << c << ", d = " << d << endl;
  if (Rational(a,b) < Rational(c,d))
    return true;
  else
    return false;
}

In other words, make your program tell you what is doing.

In this case, the two functions call themselves recursively until stack space is exhausted. Lots of times this gives a silent failure (the program merely terminates without an error message). Some times it gives a seg fault (depending on what the function(s) is/are actually doing with data space).

You must use some operations that are already defined (like arithmetic operations and/or boolean operators on expressions of ints or doubles) that can determine whether a/b is less than c/d.

Regards,

Dave
  #3  
Old 30-Nov-2005, 14:16
SergeDrago's Avatar
SergeDrago SergeDrago is offline
New Member
 
Join Date: Nov 2005
Location: Here
Posts: 6
SergeDrago is on a distinguished road

Re: Another Segmentation Fault Problem


Thanks for the tip Dave. I was able to figure it out and now it works. Now I have to go to my job.
 
 

Recent GIDBlogHalfway done! by crystalattice

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
segmentation fault? in C micheldenostra C Programming Language 1 10-Sep-2005 12:27
Please help segmentation fault problem robsmith C Programming Language 1 08-May-2005 20:34
Help with segmentation fault boris C Programming Language 1 02-Feb-2005 14:25
segmentation fault in c++ rushman8282 C++ Forum 2 26-Jan-2005 03:38
Segmentation Fault? aaroncohn C++ Forum 2 02-Jan-2005 14:22

Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The

All times are GMT -6. The time now is 05:30.


vBulletin, Copyright © 2000 - 2008, Jelsoft Enterprises Ltd.