Programm Aussschnit - Laufzeitfehler



  • Hier ist ein Ausschnitt aus meinem Programm an dem ich grad schreibe, einem Finanzplaner. In folgendem Code geht es darum dass der Benutzer nach seinem Einkommen befragt wird. Ich wollte die Antworten in dem vector "m_save_in" Speichern, und nach jedem Schleifendurchlauf den Vektor mit vector.resize(vector.size()+1) um ein Feld erhöhen.
    Doch ab dem Moment wo ich versuche über einen Iterator etwas in den Vektor reinzuschreiben kommt der Laufzeitfehler.
    Hier mal der Code ausschnit, ich hoff irgendjemand verstehts, aber wenn ich noch mehr Code poste, wirds glaub ich nur noch verwirrender:

    income.hpp

    #ifndef _INCOME_H_
    #define _INCOME_H_
    
    #include <iostream>
    #include <vector>
    #include <iterator>
    #include "user_service.hpp"
    #include "networking_data_types.hpp"
    
    class income
    {
        public:
        income();
        void detail_interview_income(); //Frägt die Details ab. 1.Betreff, 2.Preis, 3.Datum
    
        private:
        user_service ser_income; //Eigenes "user_service" Objekt, über welches die benötigten Methoden aufgerufen werden können
        std::vector<finance> m_save_in; //Zuständig zum speichern der Details. Spezieller Datentyp (siehe netw._data_types)
        std::vector<finance>::iterator iter;
        datum date;
    };
    
    #endif // _INCOME_H_
    

    //LAUFZEITFEHLER ZEILE 19! Nach Enter Bestätigung von cin
    income.cpp

    #include "income.hpp"
    #include "imp_fkt.hpp"
    
    //Konstruktor
    income::income()
    :iter(m_save_in.begin())
    {
    
    }
    //Fasst die benötigten Methoden aus "user_service" zusammen
    //Frägt den User sozusagen über die details aus (interview)
    void income::detail_interview_income()
    {
    
         do
         {
             m_save_in.resize(m_save_in.size()+1);
             imp_fkt::clean_buffer();
             iter->money_re=ser_income.cash_flow("Geldquelle: "); //Frägt nach dem Betreff/Artikel //LAUFZEITFEHLER Win-ERROR
             iter->money_amount=ser_income.amount("Geldsumme: "); //Frägt nach dem Preis
             imp_fkt::clean_buffer(); //Leer Buffer...sonst Probleme mit "goon_option()"
             ++iter;
         }
         while(ser_income.goon_option()); //Weiter Artiekl reinschreiben, oder Datum -> und abschließen (siehe user_service)
    
         date=ser_income.date(); //Nach Datum fragen
    
    }
    

    //unwichig nur nebensächlich
    networking_data_types.hpp

    struct datum
    {
        unsigned long year;
        unsigned long month;
        unsigned long day;
    };
    
    struct finance
    {
        std::string money_re; 
        unsigned long money_amount;
    };
    

    Vll. hab ich ja Glück und irgendjemand blickt durch. Vll. is für einen standard Programmierer der dass schon 10 Jahre macht ja ganz normal lesbar wie aus nem Buch, kp 🙂

    MfG
    Stromberg



  • Der Aufruf von resize kann Iteratoren ungültig machen.

    Warum benutzt du nicht einfach vector::push_back und vector::back?



  • Dass resize() die Iteratoren ungültig macht, ist mir nicht bekannt, es kann aber durchaus sein.
    Du hast den Iterator nur im Konstruktor initialisiert. Falls die income::detail_interview_income() mehrmals aufgerufen wird, überschreitest du mit dem Iterator den Speicherbereich.
    Was macht die Funktion goon_back() ? Arbeitet sie fehlerfrei?

    Wenn du nur Elemente anhängen willst, benutze die Funktion push_back(..) . Da kannst du dir deine vielen Abfragen und Iteratoren sparen 😉
    Mit back() erhältst du das letzte Element des Vektors.



  • Mh, weil ich weiß net so genau wie ich da push_back aufrufe, weil des is ja kein normaler vektor, sondern der hat den Typ "finance"...
    Ich wollt eigentlich schon push_back nehmen, wusst aber net wies geht.
    Wie ruf ich da dann push_back auf? Weil bei push_back muss man ja imemr irgendwie nen Wert angeben, ich will aber nur ein Feld weiter und no gar keinen Wert eingeben, weil ich hab ja erst alle Werte nach einem Schelfiendruchlauf...
    Kann mir jemand folgen?

    MfG
    Stromberg



  • Stromberg schrieb:

    Mh, weil ich weiß net so genau wie ich da push_back aufrufe, weil des is ja kein normaler vektor, sondern der hat den Typ "finance"..

    Das spielt keine Rolle, std::vector<> als Template kann beliebige Typen annehmen.

    Stromberg schrieb:

    do
         {
             // ..
             iter->money_re=ser_income.cash_flow("Geldquelle: "); //Frägt nach dem Betreff/Artikel //LAUFZEITFEHLER Win-ERROR
             iter->money_amount=ser_income.amount("Geldsumme: "); //Frägt nach dem Preis
             // ...
         } //...
    

    Hier hast du aber den neuen Elementen auch bereits einen Wert zugewiesen, bzw. deren Member verändert. Ich denke, bei resize() werden neue Elemente automatisch mit dem Standardkonstruktor des jeweiligen Typs initialisiert.

    Wenn du im Vornherein schon weisst, wie gross der neue, vergrösserte Vektor sein soll, kannst du das ja mit resize() erledigen. Und sonst kannst du mit push_back() neue Elemente einzeln anhängen (die notfalls auch mit dem Standardkonstruktor initialisiert werden). Du kannst deren Werte ja später noch abändern oder mit back() auf das gerade angehängte letzte Element zugreifen.



  • Ah, okay ich habs dann so gemacht:

    networking_data_types.hpp

    struct finance
    {
        finance(std::string re, unsigned long amount);
        std::string money_re; //re = engl. Betreff
        unsigned long money_amount;
    };
    

    networking_data_types.cpp

    #include <iostream>
    #include "networking_data_types.hpp"
    using namespace std;
    
    finance::finance(std::string re, unsigned long amount)
    :money_re(re),money_amount(amount)
    {
    
    }
    

    income.hpp

    #ifndef _INCOME_H_
    #define _INCOME_H_
    
    #include <iostream>
    #include <vector>
    #include "user_service.hpp"
    #include "networking_data_types.hpp"
    
    class income
    {
        public:
        void detail_interview_income(); //Frägt die Details ab. 1.Betreff, 2.Preis, 3.Datum
    
        private:
        user_service ser_income; //Eigenes "user_service" Objekt, über welches die benötigten Methoden aufgerufen werden können
        std::vector<finance> m_save_in; //Zuständig zum speichern der Details. Spezieller Datentyp (siehe new_data_types)
        datum date;
    };
    
    #endif // _INCOME_H_
    

    income.cpp

    #include <string>
    #include "income.hpp"
    #include "imp_fkt.hpp"
    using namespace std;
    
    //Fasst die benötigten Methoden aus "user_service" zusammen
    //Frägt den User sozusagen über die details aus (interview)
    void income::detail_interview_income()
    {
    
         do
         {
             string re;
             unsigned long amount;
    
             imp_fkt::clean_buffer();
             re=ser_income.cash_flow("Geldquelle: "); //Frägt nach dem Betreff/Artikel //LAUFZEITFEHLER Win-ERROR
             amount=ser_income.amount("Geldsumme: "); //Frägt nach dem Preis
             imp_fkt::clean_buffer(); //Leer Buffer...sonst Probleme mit "goon_option()"
             m_save_in.push_back(finance(re,amount));
         }
         while(ser_income.goon_option()); //Weiter Artiekl reinschreiben, oder Datum -> und abschließen (siehe user_service)
    
         date=ser_income.date(); //Nach Datum fragen
    
    }
    

    So hasts du doch gemeint oder?

    MfG
    Stromberg


Anmelden zum Antworten