为什么Sigill信号会过早存在?

时间:2017-11-01 18:07:23

标签: c++ class object

我有一个问题,我必须在两架战斗机之间的战斗中返回胜利者的名字。 战斗机的课程如下:

class Fighter
{
private:
std::string name;

int health;

int damagePerAttack;

public:
Fighter(std::string name, int health, int damagePerAttack)
{
    this->name = name;
    this->health = health;
    this->damagePerAttack = damagePerAttack;
}

~Fighter() { };

std::string getName()
{
    return name;
}

int getHealth()
{
    return health;
}

int getDamagePerAttack()
{
    return damagePerAttack;
}

void setHealth(int value)
{
    health = value;
}
};

我写了一个应该返回获胜者姓名的函数。

  std::string declareWinner(Fighter* fighter1, Fighter* fighter2, 
  std::string firstAttacker)
  {
     // Your code goes here. Have fun!
    if(firstAttacker==fighter1->getName())
    {
      while(fighter1->getHealth()!=0&&fighter2->getHealth()!=0)
      {
        fighter2->setHealth(fighter2->getHealth()-fighter1->getDamagePerAttack());
        if(fighter2->getHealth()<=0)
        {
          return fighter1->getName();
        }
        fighter1->setHealth(fighter1->getHealth()-fighter2->getDamagePerAttack());
        if(fighter1->getHealth()<=0)
        {
          return fighter2->getName();
        }
      }
    }
    else if(firstAttacker==fighter2->getName())
    {
      while(fighter1->getHealth()!=0&&fighter2->getHealth()!=0)
      {
        fighter1->setHealth(fighter1->getHealth()-fighter2->getDamagePerAttack());
        if(fighter1->getHealth()<=0)
        {
          return fighter2->getName();
        }
        fighter2->setHealth(fighter2->getHealth()-fighter1->getDamagePerAttack());
        if(fighter2->getHealth()<=0)
        {
          return fighter1->getName();
        }
      }
    }
  }

这满足了我的所有需求,但它会抛出SIGILL信号,我不知道我做错了什么。我应该如何处理它?<​​/ p>

1 个答案:

答案 0 :(得分:1)

在某些情况下,函数可能会运行到最后并退出而不返回值,这会破坏堆栈并导致SIGILL。作为一种安全措施,您可以将return语句添加到函数末尾。

std::string declareWinner(Fighter* fighter1, Fighter* fighter2, 
    std::string firstAttacker)
{
    // Your code goes here. Have fun!
        if(firstAttacker==fighter1->getName())
        {
          while(fighter1->getHealth()!=0&&fighter2->getHealth()!=0)
          {
            fighter2->setHealth(fighter2->getHealth()-fighter1->getDamagePerAttack());
            if(fighter2->getHealth()<=0)
            {
              return fighter1->getName();
            }
            fighter1->setHealth(fighter1->getHealth()-fighter2->getDamagePerAttack());
            if(fighter1->getHealth()<=0)
            {
              return fighter2->getName();
            }
          }
        }
        else if(firstAttacker==fighter2->getName())
        {
          while(fighter1->getHealth()!=0&&fighter2->getHealth()!=0)
          {
            fighter1->setHealth(fighter1->getHealth()-fighter2->getDamagePerAttack());
            if(fighter1->getHealth()<=0)
            {
              return fighter2->getName();
            }
            fighter2->setHealth(fighter2->getHealth()-fighter1->getDamagePerAttack());
            if(fighter2->getHealth()<=0)
            {
              return fighter1->getName();
            }
          }
        }
        return "No winner";   <= Add before exiting function
}

我还注意到代码中存在冗余和可能的逻辑错误。 我会像这样重写它(不改变函数签名):

std::string declareWinner(Fighter* fighter1, Fighter* fighter2, 
      std::string firstAttacker)
{ 
    Fighter *first;
    Fighter *second;
    if(firstAttacker == fighter1->getName()) {
        first = fighter2;
        second = fighter1;
    } else if (firstAttacker == fighter2->getName()) {
        first = fighter1;
        second = fighter2;
    } else {
        // Bad call parameters
        return "Bad call"; // Throw exception maybe?
    }
    // Simulating fighting
    do {
        std::swap(second,first);
        second->setHealth(second->getHealth() - first->getDamagePerAttack()); 
    } while (second->getHealth() > 0);
    return first->getName(); 

}