Fails when accessing a vector option that does not exist

Asked

Viewed 63 times

0

I made a few years ago an algorithm of inheritance and polymorphism it is working correctly but if I type 7 that is a non-existent option in the menu it returns segmentation failure instead of returning me nothing printing the phrase, what is the problem?

The menu is this below:

 O ecossistema tem 0 mamífero(s).

    Quer inserir um novo mamífero no ecossistema?
    Digite [s]-Sim ou [n]-Não: s


    Diga qual animal vai se reproduzir: 
    0: cachorro
    1: gato
    2: homem
    3: cavalo
    4: cabra
    5: leao
    6: boi
    --> 0

    O ecossistema tem 1 mamífero(s).
    Um cachorro, que emite latido.
#include <vector>
#include <iostream>

class mamifero 
{
  public: //Class is private by default then it is necessary to use public so that other classes or structs have access to the members
    mamifero(){}
    ~mamifero(){}
    virtual mamifero *reproduz() = 0; // Pure virtual constructor (and abstract, to enforce reimplementation in each derived class).
    virtual std::string nome() = 0;
    virtual std::string som() = 0;
};

//Class is private by default so it is necessary to use public
class cachorro: public mamifero 
{
  public:
    cachorro(){}
    ~cachorro(){}
    cachorro *reproduz(){ return new cachorro; }
    std::string nome(){ return "cachorro"; }
    std::string som() { return "latido"; }
};

class gato: public mamifero 
{
  public:
    gato(){}
    ~gato(){}
    gato *reproduz() { return new gato; }
    std::string nome(){ return "gato"; }
    std::string som() { return "miado"; }
};

class homem: public mamifero 
{
  public:
    homem(){}
    ~homem(){}
    homem *reproduz() { return new homem; }
    std::string nome(){ return "homem"; }
    std::string som() { return "fala"; }
};

class cavalo: public mamifero 
{
  public:
    cavalo(){}
    ~cavalo(){}
    cavalo *reproduz() { return new cavalo; }
    std::string nome(){ return "cavalo"; }
    std::string som() { return "relincho"; }
};

class cabra: public mamifero 
{
  public:
    cabra(){}
    ~cabra(){}
    cabra *reproduz() { return new cabra; }
    std::string nome(){ return "cabra"; }
    std::string som() { return "berro"; }
};

class leao: public mamifero 
{
  public:
    leao(){}
    ~leao(){}
    leao *reproduz() { return new leao; }
    std::string nome(){ return "leao"; }
    std::string som() { return "rugido"; }
};

class boi: public mamifero 
{
  public:
    boi(){}
    ~boi(){}
    boi *reproduz() { return new boi; }
    std::string nome(){ return "boi"; }
    std::string som() { return "sturro"; }
};

std::vector<mamifero *> opcoes
{
  new cachorro,  
  new gato,  
  new homem,
  new cavalo,
  new cabra,
  new leao,
  new boi
};

std::vector<mamifero *> ecossistema;

mamifero *menu(void)
{
  int n=0;
  std::cout << "\n\tDiga qual animal vai se reproduzir: ";
  for(const auto &animal: opcoes)
  std::cout << "\n\t" << n++ << ": " << animal->nome() << "";
  std::cout << "\n\t--> ";
  std::cin >> n;
  std::cin.ignore(1, '\n');
    if (n >= 0 && n < opcoes.size())return opcoes[n]->reproduz();
else
{
std::cout<<"\n\tEcosistema não encontrado.\n\tDeseja continuar? (s)im ou n(ão): ";
std::cin>>op;
if(op == 's' || op == 'S')
return menu();

else
std::cout << "\n\tGoodbye!\n\n";
}
}

mamifero *getDetails(void)
{
  std::string resposta;

  do
  {
   std::cout << "\n\tO ecossistema tem " << ecossistema.size() << " mamífero(s).\n";
   if(ecossistema.size() > 0)
   for(const auto &animal: ecossistema)
   std::cout << "\tUm " << animal->nome() << ", que emite " << animal->som() << ".\n";   
   std::cout << "\n\tQuer inserir um novo mamífero no ecossistema?\n\tDigite [s]-Sim ou [n]-Não: ";
   getline(std::cin, resposta);
   std::cout << std::endl;

   if(resposta == "s" || resposta == "S")
   ecossistema.push_back(menu());
   else
   if(resposta == "n" || resposta == "N")break;
   else
   if(resposta != "s" || resposta != "S")
   std::cout<<"\n\tOpção Inválida\n";  

  }while(resposta != "n" || resposta != "N");

  if(ecossistema.size() > opcoes.size()) std::cout<<"\n\tEcosistema nao encontrado.\n";
  else
  if(ecossistema.size() > 0)
   {
    std::cout << "\n\tAo final, o ecossistema tinha " << ecossistema.size() << " mamífero(s).\n";
    for(const auto &animal: ecossistema)
    std::cout << "\tUm " << animal->nome() << ", que emite " << animal->som() << ".\n";
    std::cout << "\n\tGoodbye!\n\n";
   }
  else
  std::cout << "\n\tAo final, o ecossistema tem " << ecossistema.size() << " mamífero.\n\n";
  return 0;
}

int main()
{
  getDetails();
}
  • After more than 40 questions I think you still don’t understand how the site works. I recommend reading [tour] and [help}. And see better how to put tags, format the question, etc.

1 answer

0


Obviously if you only have options from 0 to 6 declared it is not possible to use 7, so make sure n is in the valid track before using it, something like this:

if (n >= 0 && n < opcoes.size()) return opcoes[n]->reproduz();
return 0;

I put in the Github for future reference.

I suspect there are several other errors in the code, although it works.

  • but I wanted to do it this way because if I created a new class by inserting a new annumal the vector itself would account for and control it. if(ecosystem.size() > options.size()) Std::Cout<<" n tEcosystem not found. n"; Else

  • Ready. Are you sure it was you who did all this?

  • the code itself yes but the use of Std::vector was a friend of mine at the time of facul.

  • Now it worked.. if (n >= 0 && n < options.size())Return options[n]->plays(); Else { Std::Cout<<" n tEcosystem not found. Do you want to continue? (s) im or n(ão): "; Std::Cin>op; if(op == ’s' || op == ’S') Return menu(); Else Std::Cout << " n tGoodbye! n n"; }

Browser other questions tagged

You are not signed in. Login or sign up in order to post.