Segfault返回一个元组

是的

我一直在尝试使用2个自定义类Fraction和Integer重载+运算符。理想情况下,我希望+运算符返回最简单的操作版本(即1/4 + 3/4 == 1(整数))。我还没有找到一种动态分配返回类型的好方法,因此我尝试返回包含在Struct或元组中的多个值。我实际上尝试在main中进行操作时会遇到段错误,如下所示:

///main/////////
int main(){
  Fraction *f = new Fraction(1,4);
  Fraction *f2 = new Fraction(3,4);
  Fraction *resF = new Fraction();//results
  Integer *resI = new Integer();

  boost::tie(resF, resI) = *f+*f2; //SEGFAULT here
}

涉及的两个类是通用抽象基类的派生类,其成员和函数在此处定义:

#include <boost/tuple/tuple.hpp>
#include <iostream>
//Number class
//forward declarations for tuple
class Integer;
class Fraction;
//abstract base class
template<class T>//T is derived class
class Number{
  virtual const boost::tuple<Fraction*, Integer*> operator+ (const Number&) {};
  virtual void display(std::ostream &) const {} ;
  virtual bool operator==(const Number& rhs) const{} ;
};//end of Number class

//Integer class
class Integer: public Number<Integer>{
  int numericValue;//<! the value of the integer
  public:
  int getValue() const;//<!access private member variable numericValue
  void setValue(int);//<!set private member variable numericValue
  Integer();//<!default constructor
  Integer(int);//<!param constructor
  virtual ~Integer() {}//<!destructor
  //display
  void display(std::ostream &) const;//<!stream a display of the number
  //int == int
  bool operator==(const Integer&) const;//<! comparator int-int
  //  int + int
  const Integer operator+ (const Integer &);//<! add int+int
}; 
//DEFINITIONS////////////////////
//Default constructor
Integer::Integer(){
  numericValue = 0;
}
// param constructor
Integer::Integer(int num){
  numericValue = num;
}
//get integer value
int Integer::getValue() const{
  return this->numericValue;
}
//set integer value
void Integer::setValue(int x){
  this->numericValue = x;
}
//display int 
void Integer::display(std::ostream& stream) const{
  stream << this->numericValue<<std::endl;
}
// int + int
const Integer Integer::operator+(const Integer &rhs){
  Integer  temp = this->numericValue + rhs.numericValue;
  return temp;
}
// int == int
bool Integer::operator==(const Integer& rhs) const{
  if(this->numericValue == rhs.numericValue)
    return true;
  else
    return false;
}
//end of Integer class

//Fraction class
class Fraction: public Number<Fraction>{
  Integer numerator;
  Integer denominator;

  boost::tuple<Fraction*, Integer*> resOfAdd;

  public:
  int getNumerator();//<! to access private member
  int getDenominator();//<! to access private member
  bool isInteger;//<! flag if the fraction result of '+' can be reduced as an integer 
  bool isWhole();//!<tells if can be simplified to integer
  Integer fToI;//<! store the integer value of the fraction if it is whole 
  Fraction() = default;//<! default constructor
  Fraction(const int &, const int &);//<!param constructor
  const Fraction simplify(const Fraction &in);//<! simplifies fraction if possible
  int gcdCalculate(int  lhs, int  rhs);//!<greatest common denominator
  int lcmCalculate(const int  lhs, const int  rhs);//<!least common 
  virtual ~Fraction() {}
  //display
  void display(std::ostream &) const;
  // frac == frac 
  bool operator==(const Fraction& rhs) const;
  //frac + frac
  boost::tuple<Fraction*, Integer*>  operator+(const Fraction &);
};//end of Fraction class
//DEFINITIONS///////////////////
// param constructor 
Fraction::Fraction(const int & num, const int & den){
  numerator.setValue(num);
  denominator.setValue(den);
  if(denominator.getValue()==1){//also an integer
    fToI = Integer(numerator.getValue());
  }
  if(denominator.getValue() < 0 && numerator.getValue() > 0){//negative sign on bottom
    denominator.setValue(denominator.getValue()*-1);
    numerator.setValue(numerator.getValue()*-1); //switch it to the top
  }
  if(denominator.getValue() < 0 && numerator.getValue() < 0){//both top and bottom are negative
    denominator.setValue(denominator.getValue()*-1);
    numerator.setValue(numerator.getValue()*-1); //flip them to positive
  }
}
//get ifInteger
bool Fraction::isWhole(){
  return this->isInteger;
}
//get numerator
int Fraction::getNumerator(){
  return this->numerator.getValue();
}
//get denominator
int Fraction::getDenominator(){
  return this->denominator.getValue();
}
// display the fraction value
void Fraction::display(std::ostream & stream) const{
  stream << this->numerator.getValue() << "/" << this->denominator.getValue()<<std::endl;
}
//simplify fraction 
const Fraction Fraction::simplify(const Fraction &in){
  int gcd = gcdCalculate(in.numerator.getValue(), in.denominator.getValue());
  Fraction res = Fraction(in.numerator.getValue()/gcd, in.denominator.getValue()/gcd);
  return res;
}
//lcm - least common multiplier
int Fraction::lcmCalculate(const int  lhs, const int  rhs){
  int temp = gcdCalculate(lhs, rhs);
  return temp ? (lhs / temp * rhs) : 0;
}
//gcd - greatest common divisor
int Fraction::gcdCalculate(int a, int  b){
  return b == 0 ? a : gcdCalculate(b, a % b);
}

//frac + frac -- causing problem
boost::tuple<Fraction*, Integer*>/*numRep<Fraction, Integer>*/ Fraction::operator+(const Fraction &rhsIn){
  int numRes, denRes;
  Fraction* resF;
  Integer* resI; //if there is an integer result
  //simplify input 
  Fraction lhs = simplify(*this);
  Fraction rhs = simplify(rhsIn);
  int lcm = lcmCalculate(lhs.denominator.getValue(), rhs.denominator.getValue());
  int gcd = gcdCalculate(lhs.denominator.getValue(), rhs.denominator.getValue());
  //share denominator?
  if(lhs.denominator.getValue() == rhs.denominator.getValue()){
    numRes = lhs.numerator.getValue() + rhs.numerator.getValue();//simply add the numerators
    denRes = lhs.denominator.getValue();//keep denominator
  }
  else{
    //   a1    a2   a1*b2+a2*b1
    //   --  + -- = -----------
    //   b1    b2      b1*b2
    int a1 = lhs.getNumerator();
    int b1 = lhs.getDenominator();
    int a2 = rhs.numerator.getValue();
    int b2 = rhs.denominator.getValue();
    numRes = a1*b2 + a2*b1;
    denRes = b1*b2;
  }
  *resF = Fraction(numRes, denRes);
  //simplify
  *resF = simplify(*resF);
  if(resF->denominator.getValue() == 1){//integer result
    resF->isInteger = true;//flag
    fToI = Integer(resF->numerator.getValue());//make Integer
    resI = &fToI; //return the integer when you can
  }
  else{
    resI = new Integer(0);
  }
  //put the fraction and the (possible) integer representations into a number struct
  resOfAdd = boost::make_tuple(resF, resI);

  std::cout<<" + = ";
  resF->display(std::cout);
  delete resF;
  delete resI;
  return resOfAdd;
}

我必须做错事才能同时使用struct和tuple来得到相同的segfault错误。任何人都可以针对我的错误提出建议,或提出替代/高级解决方案来动态分配返回值吗?我了解可能无法实现动态灵活的返回类型。感谢您的时间和帮助。

Fraction* resf;
...
*resf =

resf 是未初始化的指针,并且您正在尝试将某些内容复制分配给它所指向的位置。

在此处返回指针不是一个好主意,因为它引入了所有权语义。只需按值返回:

boost::tuple<Fraction, Integer> ...

如果使用指针,则可以指示是否存在整数,请考虑使用boost::optional

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

样式:返回一个元组

在Swift中返回一个元组

返回一个元组数组

取一个元组列表并返回一个元组

合并一个元组在一个元组中填充了我的任意数量的元组并返回排序

如何为constexpr返回一个元组

QtWidgets.QFileDialog.getOpenFileName返回一个元组

返回同一个元组的函数的方法签名?

返回一个项目系列作为熊猫的元组

Python 3.9:取消IsoCalendarDate数据返回一个元组

Django .get()返回一个元组而不是对象

用Java语言返回一个元组

返回元组的第一个元素

如何创建一个返回Int元组的枚举函数?

为什么Swift Playground中的map(_ :)返回一个String而不是一个元组?

根据另一个元组中对象的成员函数返回的值构造一个元组

为什么将 Python dict 转换为元组会返回一个键元组?

如何编写一个接受一个数字并返回一个三元组列表的函数“三元组”?

Python:为什么str.split()返回一个列表,而str.partition()返回一个元组?

在元组的元组中找到一个元组

numpy.histogram 的输出元组返回一个包含两个不同长度列表的元组

返回两个元组时如何仅使用一个参数

如何将元组列表中的唯一元素作为另一个元组返回

一个方法返回一个元组,如何在C#中分配两个取该元组结果的变量

从数据库检索元组的C#列表仅返回第一个可用的元组

在元组列表中,如果tuple [0]与列表中另一个元组[0]重复,则返回tuple [1]

psycopg2 fetchone() 方法返回一个包含表示 «result» 元组的字符串的单元素元组

为什么这个 group_by / count 查询返回一个元组数组?

从DataFrame返回一个切片以及元组中的int