-1

The code have an issue in main. When I try cout<<num0-num1; alone or cout<<num0+num1; alone they work fine, but when I do them together, the code just stops print one of them and the rest of the code stops. What I mean is: If I write the main as:

    cout << "Hello world!" << endl;
    Fraction num0(90,150);
    Fraction num1(13,65);
    Fraction num2;
    cout<<num0;
    cout<<num1;
    cout<<num0-num1;
    cout<<num2;
    cout<<"idk whats wrong";

it works fine and prints out:

90/150
13/65
2/5
1/1
idk whats wrong
Process returned -1073741819 (0xC0000005)   execution time : 2.184
Press any key to continue.

however, if i write it as

   cout << "Hello world!" << endl;
    Fraction num0(90,150);
    Fraction num1(13,65);
    Fraction num2;
    cout<<num0;
    cout<<num1;
    cout<<num0-num1;
    cout<<num2;
    cout<<num0+num1;
    cout<<"idk whats wrong";

It prints:

Hello world!
90/150
13/65
2/5

Process returned -1073741819 (0xC0000005)   execution time : 2.608 s
Press any key to continue.

Here is the code : Main:

#include <iostream>
using namespace std;
#import "Fraction.h"

int main()
{
    cout << "Hello world!" << endl;

    Fraction num0(90,150);
    Fraction num1(13,65);
    Fraction num2;
    cout<<num0;
    cout<<num1;
    cout<<num0-num1;
    cout<<num2;
    cout<<num0+num1;
    cout<<"idk whats wrong";

    return 0;
}

Fraction header:

#ifndef FRACTION_H
#define FRACTION_H
#include <iostream>
using namespace std;

class Fraction
{
public:
    Fraction(int num, int denom);
    Fraction();
    Fraction reducedFraction(Fraction fract);

    Fraction operator+(const Fraction &fraction);
    Fraction operator-(const Fraction &fraction);
    Fraction& operator= (const Fraction &fraction);
    Fraction operator/(const Fraction &fraction);
    Fraction operator*(const Fraction &fraction);

    bool operator<(const Fraction &fraction);
    bool operator>(const Fraction &fraction);
    bool operator<=(const Fraction &fraction);
    bool operator>=(const Fraction &fraction);
    bool operator==(const Fraction &fraction);

    friend ostream& operator<<(ostream& os, const Fraction& fraction);
    friend istream& operator>>(istream& is,  Fraction& fraction);

    void setNum(int num);
    int getNum();
    void setDenom(int denom);
    int getDenom();
    virtual ~Fraction();


private:
    int num;
    int denom;
    int* arrN;
    int* arrD ;
    int* arrC;
};

#endif // FRACTION_H

Fraction.cpp

#include "Fraction.h"
Fraction::Fraction()
{
    num=1;
    denom=1;
}
Fraction::Fraction(int num,int denom)
{
    this->num=num;
    this->denom = denom;
}
void Fraction::setNum(int num)
{
    this->num = num;
}
void Fraction::setDenom(int denom)
{
    this->denom = denom;
}
int Fraction::getDenom()
{
    return denom;
}
int Fraction::getNum()
{
    return num;
}
Fraction Fraction::operator+(const Fraction& fraction)
{
    Fraction tmp;
    tmp.num=(this->num*fraction.denom)+(fraction.num*this->denom);
    tmp.denom =this->denom*fraction.denom;
    return reducedFraction(tmp);

}
Fraction Fraction::operator-(const Fraction &fraction)
{
    Fraction tmp;
    tmp.num=(this->num*fraction.denom)-(fraction.num*this->denom);
    tmp.denom =this->denom*fraction.denom;
    return reducedFraction(tmp);

}
Fraction Fraction::operator*(const Fraction &fraction){
    Fraction tmp;
    tmp.num=this->num*fraction.num;
    tmp.denom=this->denom*fraction.denom;
    return reducedFraction(tmp);

}
Fraction Fraction::operator/(const Fraction &fraction){
    Fraction tmp;
    tmp.num=this->num*fraction.denom;
    tmp.denom=this->denom*fraction.num;
    return reducedFraction(tmp);

}
bool Fraction::operator==(const Fraction &fraction){
    if((this->num/this->denom)==(fraction.num/fraction.denom)){
            return true;
    }
    else {
        return false;
    }
}
bool Fraction::operator>(const Fraction &fraction){
    if((this->num/this->denom)>(fraction.num/fraction.denom)){
            return true;
    }
    else {
        return false;
    }
}
bool Fraction::operator<(const Fraction &fraction){
    if((this->num/this->denom)<(fraction.num/fraction.denom)){
            return true;
    }
    else {
        return false;
    }
}
bool Fraction::operator>=(const Fraction &fraction){
    if((this->num/this->denom)>=(fraction.num/fraction.denom)){
            return true;
    }
    else {
        return false;
    }
}
bool Fraction::operator<=(const Fraction &fraction){
    if((this->num/this->denom)<=(fraction.num/fraction.denom)){
            return true;
    }
    else {
        return false;
    }
}
Fraction& Fraction::operator= (const Fraction &fraction)
{
    this->num=fraction.num;
    this->denom = fraction.denom;
    return *this;

}
ostream& operator<<(ostream& os, const Fraction& fraction)
{
    os<<fraction.num<<"/"<<fraction.denom<<endl;
    return os;
}


Fraction Fraction::reducedFraction( Fraction fract)
{
    int* arrN = new int[fract.num];
    int* arrD = new int[fract.denom];
    int* arrC;
    int countN=0;
    int countD=0;
    for (int i = 2 ; i<=fract.num; i++)
    {
        if (fract.num%i==0)
        {
            arrN[countN]=i;
            countN++;
        }
    }
    for (int i = 2 ; i<=fract.denom; i++)
    {
        if (fract.denom%i==0)
        {
            arrD[countD]=i;
            countD++;
        }
    }
    if (countN>=countD)
    {
        arrC = new int[countN];
    }
    else
    {
        arrC = new int[countD];
    }
    int countC =0;

    for ( int i = 0 ; i <countN; i++)
    {
        for (int j=0; j<countD; j++)
        {
            if(arrN[i]==arrD[j])
            {
                arrC[countC]=arrN[i];
                countC++;

            }
        }
    }
    int maxN = arrC[0];
    for ( int i =1; i<countC; i++)
    {
        if (arrC[i]>maxN)
        {
            maxN=arrC[i];
        }

    }
    Fraction tmp;
    tmp.num = fract.num/maxN;
    tmp.denom=fract.denom/maxN;
    return tmp;

}

Fraction::~Fraction()
{
    delete[]arrC;
    delete[]arrN;
    delete[]arrD;

}
Marek R
  • 32,568
  • 6
  • 55
  • 140
iAmTired
  • 21
  • 3
  • 3
    You are breaking the rule of 3/5/0 and are missing the copy and/or move constructor and assignment operators. Change your raw arrays to `std::vector` and follow the rule of 0. – Richard Critten May 14 '21 at 17:48
  • Does this answer your question? [What is The Rule of Three?](https://stackoverflow.com/questions/4172722/what-is-the-rule-of-three) – Richard Critten May 14 '21 at 17:48
  • You apologized for the code being messy, which is a good start. If you try to tidy up the code and reduce it to the smallest possible example that still demonstrates the problem, you may well discover what the problem is. – Tim Randall May 14 '21 at 17:57
  • I do not get this vote downs and close votes! Yes he is a beginner issue is simple, but title is fine, all needed information is provided. For a new member it is quite well asked question. Please always explain issue when voting down. – Marek R May 14 '21 at 18:00
  • `reducedFraction` looks like a really painful way of reducing a fraction when [std::gcd](https://en.cppreference.com/w/cpp/numeric/gcd) exists. (And even if it didn't, Euclid's algorithm is faster and simpler than trying to build up prime factorizations.) – Nathan Pierson May 14 '21 at 18:00
  • @MarekR the code uses a class with raw pointers, returns from methods by value and breaks the rule of 3/5/0. It should be closed as a duplicate. – Richard Critten May 14 '21 at 18:04
  • Minor `const`-correctness suggestion: Just like `operator+`, `operator-`, etc take their right hand side by `const` reference, they should be `const` member functions because they don't mutate the left hand side. – Nathan Pierson May 14 '21 at 18:10
  • @MarekR potential dup is comment number 2 – Richard Critten May 14 '21 at 18:10

1 Answers1

1

The error looks like caused by the destructor that is freeing uninitialized pointers.

The member variables that are not used other than causing error

    int* arrN;
    int* arrD ;
    int* arrC;

and the deleting statement just for causing error

    delete[]arrC;
    delete[]arrN;
    delete[]arrD;

should be removed.

After that, the local arrays used in the reducedFraction function should be deleted at the end of the function, before returning. Otherwise the arrays will be leaked.


    Fraction tmp;
    tmp.num = fract.num/maxN;
    tmp.denom=fract.denom/maxN;

    // free the arrays
    delete[] arrN;
    delete[] arrD;
    delete[] arrC;

    return tmp;

}
MikeCAT
  • 73,922
  • 11
  • 45
  • 70