Fehlermeldung



  • Ich habe folgenden Code:

    Passagier.h

    #ifndef PASSAGIER_H
    #define PASSAGIER_H
    #include <string>
    #include <iostream>
    using namespace std;
    
    
    class Passagier
    {
    public:
        Passagier();
        Passagier(string name);
    
        string getName() const;
        void setName(const string &value);
    
        int getBuchungsnummer() const;
        void setBuchungsnummer(int value);
    
    private:
        string name;
        int Buchungsnummer;
        static int cnt;
    };
    
    #endif // PASSAGIER_H
    
    

    Passagier.cpp

    #include "passagier.h"
    
    Passagier::Passagier()
    {
    
    }
    
    Passagier::Passagier(string name) {
        this->name = name;
        this->Buchungsnummer = cnt;
        cnt++;
    }
    
    string Passagier::getName() const
    {
        return name;
    }
    
    void Passagier::setName(const string &value)
    {
        name = value;
    }
    
    int Passagier::getBuchungsnummer() const
    {
        return Buchungsnummer;
    }
    
    void Passagier::setBuchungsnummer(int value)
    {
        Buchungsnummer = value;
    }
    
    
    int Passagier::cnt = 0;
    

    Flug.h

    #ifndef FLUG_H
    #define FLUG_H
    #include <vector>
    #include "passagier.h"
    #include <iostream>
    using namespace std;
    
    
    class Flug
    {
    public:
        Flug();
    
        void passagierHinzufuegen(Passagier p);
        void passagierLoeschen(int nr);
        void passagiereAusgeben();
    
    private:
        vector<Passagier> flight;
    
    };
    
    #endif // FLUG_H
    
    

    FLug.cpp

    #include "flug.h"
    
    Flug::Flug()
    {
    
    }
    
    void Flug::passagierHinzufuegen(Passagier p) {
        flight.push_back(p);
        cout << p.getName() << " wurde hinzugefuegt" << endl;
    }
    
    void Flug::passagierLoeschen(int nr) {
    
        for(int i=0;i<flight.size();i++)
        {
            if(flight[i].getBuchungsnummer() == nr)
            {
               for(int j=i;j<flight.size();j++) {
                   flight[j] = flight[j+1];
               }     flight.pop_back();
            }
        }
    }
    
    void Flug::passagiereAusgeben() {
        for(int i=0;i<flight.size();i++) {
            cout << "----------------------------------" << endl;
            cout << flight[i].getName() << endl;
            cout << flight[i].getBuchungsnummer() << endl;
            cout << "----------------------------------" << endl;
        }
    }
    
    

    Und die Main

    #include <iostream>
    #include "flug.h"
    
    using namespace std;
    
    
    void flugBuchen(Flug &t) {
    
        cout << "Name: ";
           string name;
           cin >> name;
    
        Passagier tmp(name);
        t.passagierHinzufuegen(tmp);
    }
    
    void flugStornieren( Flug &t) {
        cout << "nr" ;
        int nr;
        cin >> nr;
    t.passagierLoeschen(nr);
    
    }
    
    int main()
    {
    char eingabeMenu;
    Flug f;
    
    do {
    
    cout << "(a) Flug buchen" << endl;
    cout << "(b) Flug stornieren" << endl;
    cout << "(c) Anzeige aller Buchungen" << endl;
    cout << "(x) Beenden" << endl;
    
    cout << "Eingabe: ";
    cin >> eingabeMenu;
    
    
    switch (eingabeMenu)
    {
    
    case 'a' :
        flugBuchen(f);
        break;
    
    case 'b': int nr;
        cout << " nr ";
        cin >> nr;
        f.passagierLoeschen(nr);
        break;
    
    case 'c' : f.passagiereAusgeben();
        break;
    
    default: cout << "Fehler!" << endl; break;
    
    }
    
    
    
    }while (eingabeMenu != 'x');
    
        return 0;
    }
    

    Wenn ich das Programm ausführe bekomme ich bei Eingabe b folgende Fehlermeldung:

    terminate called after throwing an instance of 'std::bad_alloc'
      what():  std::bad_alloc
    

    Ich hab mich ein bisschen zu dieser Fehlermeldung eingelesen.
    Sie tritt auf wenn mit new neuer Speicher allokiert wird, dieser aber keinen Plaz mehr hat.
    Ich verstehe aber nicht wie das bei meinem Code der Fall sein kann.
    Habt ihr zufällig eine Idee wie das zustande kommt?



  • Das ganze in lesbar:

    #include <vector>
    #include <string>
    #include <iostream>
    
    class Passagier
    {
    public:
    	Passagier() {};
    	
    	Passagier(std::string name)
    	{
    		this->name = name;
    		this->Buchungsnummer = cnt;
    		cnt++;
    	}
    
    	std::string getName() const { return name; };
    	void setName(const std::string& value) { name = value; }
    
    	int getBuchungsnummer() const { return Buchungsnummer; }
    	void setBuchungsnummer(int value) { Buchungsnummer = value; }
    
    private:
    	std::string name;
    	int Buchungsnummer;
    	static int cnt;
    };
    
    int Passagier::cnt = 0;
    
    class Flug
    {
    public:
    	Flug() {};
    
    	void passagierHinzufuegen(Passagier p)
    	{
    		flight.push_back(p);
    		std::cout << p.getName() << " wurde hinzugefuegt" << std::endl;
    	}
    
    	void passagierLoeschen(int nr)
    	{
    		for (int i = 0; i < flight.size(); i++)
    		{
    			if (flight[i].getBuchungsnummer() == nr)
    			{
    				for (int j = i; j < flight.size(); j++) {
    					flight[j] = flight[j + 1];
    				}     flight.pop_back();
    			}
    		}
    	}
    	void passagiereAusgeben()
    	{
    		for (int i = 0; i < flight.size(); i++) {
    			std::cout << "----------------------------------" << std::endl;
    			std::cout << flight[i].getName() << std::endl;
    			std::cout << flight[i].getBuchungsnummer() << std::endl;
    			std::cout << "----------------------------------" << std::endl;
    		}
    	}
    
    private:
    	std::vector<Passagier> flight;
    
    };
    
    void flugBuchen(Flug& t)
    {
    	std::cout << "Name: ";
    	std::string name;
    	std::cin >> name;
    
    	Passagier tmp(name);
    	t.passagierHinzufuegen(tmp);
    }
    
    void flugStornieren(Flug& t)
    {
    	std::cout << "nr";
    	int nr;
    	std::cin >> nr;
    	t.passagierLoeschen(nr);
    
    }
    
    int main()
    {
    	char eingabeMenu;
    	Flug f;
    
    	do {
    
    		std::cout << "(a) Flug buchen" << std::endl;
    		std::cout << "(b) Flug stornieren" << std::endl;
    		std::cout << "(c) Anzeige aller Buchungen" << std::endl;
    		std::cout << "(x) Beenden" << std::endl;
    		std::cout << "Eingabe: ";
    		std::cin >> eingabeMenu;
    
    
    		switch (eingabeMenu)
    		{
    
    		case 'a':
    			flugBuchen(f);
    			break;
    
    		case 'b': int nr;
    			std::cout << " nr ";
    			std::cin >> nr;
    			f.passagierLoeschen(nr);
    			break;
    
    		case 'c': f.passagiereAusgeben();
    			break;
    
    		default:
    			std::cout << "Fehler!" << std::endl;
    			break;
    		}
    	} while (eingabeMenu != 'x');
    }
    

    Für den Anfang lass bitte using namespace in Headerdateien bleiben.



  • @TheDude sagte in Fehlermeldung:

    flight[j] = flight[j+1];

    Das geht beim letzten Eintrag immer schief, da dann j+1 hinter dem letzten Eintrag liegt.


  • Mod

    Das passagierLöschen ist so ein Antipattern, das hat sogar einen Wikipedia-Eintrag, wie es richtig geht:
    https://en.wikipedia.org/wiki/Erase–remove_idiom

    Zur bad_alloc: Riecht nach Endlosschleife, wenn die Streams in Fehlerzustand gehen, da die Rückgabewerte nie geprüft werden.



  • Abgesehen davon schreit das nach find_if. Statt in einer Schleife selbst nach den zu löschenden Kandidaten zu suchen kannst du das über ein Lambda erledigen. Ich kenne deinen Kenntnisstand nicht, aber früher oder später solltest du dich damit beschäftigen:

    #include <algorithm>
    
    void flug::passagierLoeschen( int buchungs_nummer )
    {
       auto predicate = [&]( Passagier const& passagier )
       {
          return passagier.getBuchungsnummer() == buchungs_nummer;
       };
       auto pos = std::find_if( flight.begin(), flight.end(), predicate );
       if( pos != flight.end() )
       {
          flight.erase( pos );
       }
    }
    

    Gibt´s Gründe dafür, dass die Liste der Passagiere flight, und nicht Passagiere heißt?

    Edit:
    SeppJ war schneller



  • @Swordfish Danke 😃



  • @DocShoe Danke für den Tipp. Ich werd mich mal reinlesen.
    Bin noch relativ neu aber du hast recht. Früher oder später, also warum nicht jetzt 😃



  • @SeppJ Vielen Dank. Diese Art ist wirklich viel besser



  • @manni66 Stimmt. Danke 😃



  • Ich habe es hingekriegt. Danke euch allen erstmal 😃
    Eine Frage hätte ich noch:

    Nach meinem Post habe ich weiter versucht das Problem zu lösen und hab nur eine ganz kleine Änderung gemacht:

    void Flug::passagierLoeschen(int nr) {
    
        for(int i=0;i<flight.size();i++)
        {
            if(flight[i].getBuchungsnummer() == nr)
            {
               for(int j=i;j<flight.size()-1;j++) {      // -1 um nicht überzulaufen
                   flight[j] = flight[j+1];
               }     flight.pop_back();
            }
        }
    }
    

    Ich hab noch nicht viel Erfahrung, ist es so auch okay oder sollte man eher davon abraten?



  • was gibt size() zurück und was ist wenn die Anzahl 0 ist?



  • @Swordfish sagte in Fehlermeldung:

    was gibt size() zurück und was ist wenn die Anzahl 0 ist?

    Das geht hier gut, weil mit Anzahl 0 nichts gelöscht wird und somit die innere Schleife nicht ausgeführt wird. Es wird auch immer nur ein Eintrag gelöscht.

    Aber der Einwand ist richtig.



  • @manni66 Ein vernünftig bedienter compiler sollte auf signed/unsigned mismatch in comparision hinweisen ...



  • @Swordfish sagte in Fehlermeldung:

    @manni66 Ein vernünftig bedienter compiler sollte auf signed/unsigned mismatch in comparision hinweisen ...

    Ja



  • Danke für eure Antworten Manni und Swordfish 😃
    Ihr seid wirklich hilfreich



  • @manni66 sagte in Fehlermeldung:

    Ja

    das meinte ich bzgl. .size() - 1.



  • @Swordfish sagte in Fehlermeldung:

    @manni66 sagte in Fehlermeldung:

    Ja

    das meinte ich bzgl. .size() - 1.

    for (std::size_t j = i; j < flight.size()-1; j++) {

    Ich wüsste nicht, wie ich den gcc hier zu einer Warnung veranlassen soll.



  • da nicht aber im originalcode.



  • @Swordfish sagte in Fehlermeldung:

    da nicht aber im originalcode.

    Dann verstehe ich

    @Swordfish sagte in Fehlermeldung:

    @manni66 sagte in Fehlermeldung:

    Ja

    das meinte ich bzgl. .size() - 1.

    nicht.



  • Ach menno. Bei

    @TheDude sagte in Fehlermeldung:

           for(int j=i;j<flight.size()-1;j++) {      // -1 um nicht überzulaufen
    

    sollte es einen signed/unsigned mismatch geben was einen eigentlich dazu bringen sollte darüber nachzudenken was bei .size() == 0 und 0 - 1 passiert.


Log in to reply