2017-11-01 4 views
1

나는 두명의 전투기 사이의 싸움에서 승자의 이름을 돌려줘야하는 문제가있다. 다음과 같이 전투기의 클래스는 다음과 같습니다Sigill 신호가있는 이유는 무엇입니까?

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(); 
     } 
     } 
    } 
    } 

이것은 내 모든 필요를 충족 시키지만, 신호가 울리고, 내가 뭘 잘못했는지 모른다. 어떻게 처리해야합니까?

+0

어떻게 당신은 declareWinner에 충돌이 아닌 다른 곳에서 알 수 있습니까? – mnistic

+1

NULL- 포인터에 대한 전투기를 검사하는 것 외에도 declareWinner()를 호출 할 때마다 문자열을 반환해야합니다. – Gerriet

+0

@mnistic 어디에서 충돌이 발생하는지 모르겠다. 나는 그것이 그 신호를 던지는 것을 안다. 코드 워어에서이 문제를 해결하기 위해 노력하고 있습니다. 그래서 그 신호를 보여줍니다. I.ve는 그것을 실행하기 위해 코드 블록에 넣으려고했는데, 몇 가지 간단한 예제의 경우 잘 작동합니다. –

답변

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(); 

} 
+0

마지막에 return 문을 추가하는 것이 중요하다는 것을 이해합니다.'if' 나'else if' 문 중 하나가 정확하다는 사실을 확신하지 못했을 때 사용했을 것입니다. 하지만, 당신의 기능을 시도하고 작동하고 더 이상 그 신호를 던져하지 않습니다. firstAttacker가 전투기 중 하나라는 사실을 테스트 한 결과, firstAttacker가 전투기의 이름과 다를 수 있다는 사실과 관련이 없습니다. –

+1

또한 조건이 조기에 종료되어 아무 것도 반환하지 않을 수있는 문제가 있습니다. 괄호를 사용해야합니다 : while ((fighter1-> getHealth()! = 0) && (fighter2-> getHealth()! = 0)). 그러나 요점은 모든 조건을 충족시키지 못하는 상황이라면 언제든지 기능에서 조기 반환에 대한 elses 또는 다른 경비원을 사용해야합니다.컴파일러는 이것에 대한 경고를 줄 것입니다. – Victor

관련 문제