Segmentation Error. I Think?

I'm almost complete with this program but am getting a reoccurring error that I can't diagnose.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#ifndef RATIONAL_HPP
#define RATIONAL_HPP

#include <cstdlib>
#include <iosfwd>
#include <iostream>
#include <stdlib.h>
#include <assert.h>


// Mathematical helper functions.
//
// NOTE: These are defined in rational.cpp.
int gcd(int, int);
int lcm(int, int);


// Represents a rational number. The rational numbers are the set of
// numbers that can be represented as the quotient of two integers.
class Rational
{
   // TODO: Define the following:
   // 1. A default constructor
   int n, d;
   public:
   Rational() : n(0), d(1){}
   // 2. A constructor that takes an integer value
   Rational(int num) : n(num), d(1){}
   // 3. A constructor that takes a pair of values
   Rational (int numerator, int denom) : n(numerator), d(denom)
    {
        assert(d != 0);
        int gcdnum;
        if ((numerator % denom)!= 0)
        {
            //We do nothing here
        }
        else
        {
            gcdnum = gcd(numerator, denom);
            numerator /= gcdnum;
            denom /= gcdnum;
            Rational (numerator, denom);
        }
    }

      // Returns the numerator.
      int num() const
      {
          return n;
      }

      // Returns the denominator
      int den() const
      {
          return d;
      }

};


// 1. Comparing two rational numbers for equality:
//    - r1 == t2
    bool operator==(Rational a, Rational b);
//    - r1 != r2
    bool operator!=(Rational a, Rational b);
// 2. Ordering rational numbers
//    - r1 < r2
    bool operator < (Rational a, Rational b);
//    - r1 > r2
    bool operator > (Rational a, Rational b);
//    - r1 <= r2
    bool operator <= (Rational a, Rational b);
//    - r1 >= r2
    bool operator >= (Rational a, Rational b);
// 3. The standard arithmetic operators
//    - r1 + r2
    Rational operator + (Rational a, Rational b);
//    - r1 - r2
    Rational operator - (Rational a, Rational b);
//    - r1 * r2
    Rational operator * (Rational a, Rational b);
//    - r1 / r2
    Rational operator / (Rational a, Rational b);

// These are provided for you.
//
// NOTE: They are defined in rational.cpp.
std::ostream& operator<<(std::ostream&, Rational);
std::istream& operator>>(std::istream&, Rational&);

#endif

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#include "rational.hpp"


#include <iostream>

#include <unistd.h>

// Encapsulate all of the Rational tests.
struct Test_rational
{
  void default_ctor()
  {
    // Check the default contructor.
    Rational r;
    assert(r == Rational(0, 1));
    std::cout << " Rational(0, 1) default constructor passed" << std::endl;
    assert(r == Rational(0, 2));
    std::cout << " Rational(0, 2) default constructor passed" << std::endl;
  }


  void integer_ctor()
  {
    Rational r(3);
    assert(r == Rational(3, 1));
    std::cout << " Rational(3, 1) passed" << std::endl;
  }


  void rational_ctor()
  {
    // This must fail.
//    assert(Rational(1, 0));

    // Check that copies work as expectded.
    Rational r(3, 4);
    assert(r == Rational(3, 4));
    std::cout << " Rational copy constructor passed" << std::endl;
  }

  void equality()
  {
    Rational r1(1, 2);
    Rational r2(2, 4);
    Rational r3(1, 4);
    assert(r1 == r2);
    std::cout << " Rational equality OL passed" << std::endl;
    assert(r1 != r3);
    std::cout << " Rational inequality OL passed" << std::endl;
  }

  void ordering()
  {
    Rational r1(1, 4);
    Rational r2(1, 2);
    assert(r1 < r2);
    std::cout << " Rational comparison LT OL passed" << std::endl;
    assert(r2 > r1);
    std::cout << " Rational comparison GT OL passed" << std::endl;
    assert(r1 <= r1);
    std::cout << " Rational comparison LT= OL passed" << std::endl;
    assert(r1 >= r1);
    std::cout << " Rational comparison GT= OL passed" << std::endl;
  }

  void arithmetic()
  {
    Rational r1(1, 2);
    Rational r2(1, 4);
    assert(r1 + r2 == Rational(3, 4));
    std::cout << " Rational addition passed" << std::endl;
    assert(r1 - r2 == Rational(1, 4));
    std::cout << " Rational subtraction passed" << std::endl;
    assert(r1 * r2 == Rational(1, 8));
    std::cout << " Rational multiplication passed" << std::endl;
    assert(r1 / r2 == Rational(2, 1));
    std::cout << " Rational division passed" << std::endl;
  }

  void interoperate()
  {
    Rational r1 = 1;
    std::cout  << (r1 == 1); // prints true
    std::cout  << (2 == r1); // prints false
    std::cout  << (r1 < 2); // prints true
    std::cout  << (0 < r1); // prints false
    std::cout  << (r1 + 2) << std::endl; // prints 3/1 (or just 3)
  }

  void rc()
  {
     // Determine if input is coming from a terminal.
     bool term = isatty(0);

    // This will continue reading until it reaches the end-of-input.
    // If you are using this interactively, type crtl-d to send the
    // end of input character to the terminal.
    while (std::cin)
    {
      Rational r1;
      Rational r2;
      std::string op;

      if (term)
        std::cout << "> ";

      std::cin >> r1 >> op >> r2;
      if (!std::cin)
        break;

      // FIXME: Add all of the other overlaoded operators by adding
      // cases for each of them.
      if (op == "==")
        std::cout << std::boolalpha << (r1 == r2) << '\n';
      else if (op == "!=")
        std::cout << std::boolalpha << (r1 == r2) << '\n';
      else if (op == ">")
        std::cout << std::boolalpha << (r1 == r2) << '\n';
      else if (op == "<")
        std::cout << std::boolalpha << (r1 < r2) << '\n';
      else if (op == ">=")
        std::cout << std::boolalpha << (r1 >= r2) << '\n';
      else if (op == "<=")
        std::cout << std::boolalpha << (r1 <= r2) << '\n';
      else if (op == "+")
        std::cout << (r1 + r2) << '\n';
      else if (op == "-")
        std::cout << (r1 - r2) << '\n';
      else if (op == "*")
        std::cout << (r1 * r2) << '\n';
      else if (op == "/")
        std::cout << (r1 / r2) << '\n';
      else
        std::cerr << "invalid operator: " << op << '\n';
    }

    // If we got to the end of the file without fatal errors,
    // return success.
    if (std::cin.eof())
      return;

    // Otherwise, diagnose errors in input and exit with an error
    // code.
    if (std::cin.fail())
    {
      std::cerr << "input error\n";
      exit(1);
    }
  }

  // The test runner for this test class.
  void run()
  {
    default_ctor();
    integer_ctor();
    rational_ctor();
    equality();
    ordering();
    arithmetic();
    interoperate();
    rc();
  }
};


int
main()
{
  Test_rational test;
  test.run();
}


As far I as I know, the program stops when default_ctor is called. Help would be appreciated.
Have you run the program with your debugger? Your debugger will be able to tell you exactly where it detects the problem and you should be able to view the variables at the time of the crash. Once you know where the problem is detected you should then be able to backtrace to the actual problem.
My debugger is crashing when the program gets to line 43 of the rational.hpp. I do not understand why its doing this. No errors are popping up.
My debugger is crashing when the program gets to line 43 of the rational.hpp.

You really shouldn't have executable code inside a header file.

Did you set a break point somewhere early in main() and single step through the code in question?

Okay, so I put my constructor code inside my cpp file.

And yeah, I stepped through the code.

I step into
 
assert(r == Rational(0, 1));


Which calls this constructor code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Rational (int numerator, int denom) : n(numerator), d(denom)
    {
        assert(d != 0);
        int gcdnum;
        if ((numerator % denom)!= 0)
        {
            //We do nothing here
        }
        else
        {
            gcdnum = gcd(numerator, denom);
            numerator /= gcdnum;
            denom /= gcdnum;
            Rational (numerator, denom);
        }
    }


I step through this and the program fails when after I reach the last line

 
Rational (numerator, denom);

What do you think line 14 is doing? You're calling your constructor recursively to no productive purpose.

BTW, line 1 is incorrect if it is in a .cpp file. It should be:
 
Rational::Rational (int numerator, int denom) : n(numerator), d(denom)


Last edited on
Oh yeah, sorry; I have line 1 correctly in my cpp, I just posted it here wrong. Thanks for the heads up though.

Okay ,yeah I think line 14 was my problem. I mistakenly thought that I needed to do that in order to assign my numerator and denom.
Topic archived. No new replies allowed.