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.hppstruct 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 Funktiongoon_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
Mitback()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 mitpush_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 mitback()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