Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

13.01.2015, 04:51

[gelöst] C++ exception: std::invalid_argument at memory location 0x0055F26C | Datein auslesen | String position ermitteln | std::str.eof() | std::str.find()

Hallo Leute,

sitze Gerade an einer "Simulation". Dabei gibt es 10.000 Eingangsdaten, die der Nutzer je nach Bedarf auf bis zu 100 Eingangsdaten reduzieren kann.
Die Daten sind in einer Textdatei gespeichert und haben folgende Form:

"0.00/0.5/0.987
0.01/0.51/0.986
...[10.000 mal]
"

Der folgende Codeausschnitt demonstriert wie die Daten ausgelesen und reduziert werden. Das Prinzip: wenn x Daten verwendet werden sollen, dann soll jede 10.000/x-te Zeile ausgelesen werden.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
std::string tmp;                                  //Zum Auslesen der Textdat
[..]
int SlashPosFirst;                                //Position des ersten Slashes
bool bFoundSlashPosFirst = false;
int SlashPosSecond;                           //Position des zweiten Slashes
std::string testString = "/";                 //Um zu prüfen, ob char ein Slash ist -> geht sicher eleganter, war für mich in dem Moment einfacher

//Temporäre Variablen um Ausgelesene Daten zwischenzuspeichern (mehr Übersicht)
float fTmpH;
float fTmpU;
float fTmpBx;
std::vector <float> Bx;  //Interessant sind später nur die Unterschiede zwischen zwei aufeinanderfolgenden Werten (Anstieg)

//Startwerte in Q laden -> Q wurde im Headder deklariert: std::vector<Vector2D> Q; //Bezeichnung folgt externen Papier // Vector2D eigene schlanke Vektor Klasse
std::fstream fstrLoadData;
fstrLoadData.open(strLoadSource);

for (int j = 1; j <= 10000; j++)
{
    getline(fstrLoadData, tmp);     //nächste Zeile Laden

    for (int k = 0; k < m_GridSize; k++)
    {
        if (j == vecLineList[k])
        {
            //Zeile auseinandernehmen und Daten Setzen
                //Trennstrich Position ermitteln
            for (int i = 0; i < tmp.length(); i++)
            {
                if (tmp[i] == testString[0])        //Prüfung auf Slash
                {
                    if (!bFoundSlashPosFirst)
                    {
                        SlashPosFirst = i;
                        bFoundSlashPosFirst = true;
                    }
                    else
                    {
                        SlashPosSecond = i;
                    }
                } //if(tmp[i] == testString[0])
            }

                //Ausgelesene Werte Zuweisen
            fTmpH = std::stof(tmp.substr(0, SlashPosFirst));
            fTmpU = std::stof(tmp.substr(SlashPosFirst + 1, SlashPosSecond - SlashPosFirst - 1));
            fTmpBx = std::stof(tmp.substr(SlashPosSecond + 1, tmp.length() - SlashPosSecond - 1));

            Q.push_back(Vector2D(fTmpH, fTmpH*fTmpU));
            Bx.push_back(fTmpBx);

                               //Rückmeldung an User - wie viele Daten ausgelesen wurden
            std::cout << Q.size() << std::endl;
                    
            k = m_GridSize; //For-Schleife vorzeitig verlassen,  da andere Werte nicht mehr geprüft werden müssen
        }//if(j == vecLineList[k]) - passende Zeile gefunden
    }//for (int k = 0; k < m_GridSize; k++)         
}//for(int j = 1; j<=10000; j++

fstrLoadData.close();


Nun ist es so, dass ein paar Werte eingelesen werden und ab einem Wert erscheint oben genannte Ausnahme. Der Witz ist jedoch, wenn ich eine andere Startdaten einlesen lasse (Also andere Textdatei) funktioniert das Ganze - nun bin ich auf die Idee gekommen, dass die Textdatei beschädigt sein muss. Ich habe sie aber neu erzeugt und in das entsprechende Verzeichnis kopiert - selbes Problem.

Ich geh jetzt auf jeden Fall erst einmal schlafen und träume wahrscheinlich von unbehandelten Ausnahmen ;(
VG Mah0ney

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »Mah0ney« (13.01.2015, 16:52) aus folgendem Grund: Problem gelöst; Flags für Suche einfügen


2

13.01.2015, 06:11

Die äussere for-Schleife mal so umbauen das sie auf eof prüft bzw. ne while-Schleife draus machen.

Gruß Koschi

Edit: ich würde auch std::String::find nutzen anstatt selber zu suchen!
Wer aufhört besser werden zu wollen hört auf gut zu sein!

aktuelles Projekt:Rickety Racquet

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Koschi« (13.01.2015, 06:43)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

3

13.01.2015, 06:47

Was spricht dagegen den Debugger zu benutzen? Der sollte an der Zeile anhalten, wo das Problem vorliegt. Ich würde allerdings mal raten, dass die ganzen substring-Aufrufe das Problem sind. Du prüfst die verwendeten Indices überhaupt nicht. Da ist mit Garantie irgendeiner 0, -1 oder entspricht 'length-1', was dann eben invalide Argumente sind, wenn da 1 abgezogen oder addiert wird. Berechne die Indices separat und lass sie ausgeben, wenn Du mit dem Debugger nicht zurecht kommst. Im letzteren Fall solltest Du Dich unbedingt damit beschäftigen. Ohne den kann ein Programmierer nicht eigenständig arbeiten.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

4

13.01.2015, 10:57

Ich nehme an, du verwendest Visual Studio? In dem Fall einfach mal unter "Debug" > "Exceptions" die "C++ Exceptions" anwählen, dann bleibt der Debugger autom. stehen wo eine Exception fliegt und du kannst am Call Stack raufgehen und schaun, wo das Problem ist... ;)

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

5

13.01.2015, 11:33

Ach das muss man manuell aktivieren? Ist das kein default? (Falls nein, ist es wohl einfach zu lange her, dass ich das bei mir aktiviert habe)
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

6

13.01.2015, 11:34

Ach das muss man manuell aktivieren? Ist das kein default? (Falls nein, ist es wohl einfach zu lange her, dass ich das bei mir aktiviert habe)

Nope, muss man für jedes Projekt erst manuell aktivieren.

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »dot« (13.01.2015, 11:43)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

7

13.01.2015, 13:13

Und mein letztes ist schon 2 Jahre alt :D
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

8

13.01.2015, 16:49

Vielen Dank!

Woran es genau lag, habe ich zwar immer noch nicht herausgefunden, habe aber den Code wie von Koschi vorgeschlagen umgebaut.

Für die Zukunfts-Spieleprogrammierer ist hier noch einmal der geänderte Code abgedruckt:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
fstrLoadData.open(strLoadSource);

int j = 0;                           //einfügen für die Prüfung if(j==vecLineList[k])
while (!fstrLoadData.eof())  //statt der bisherigen For-Schleife
{
        j++;
    getline(fstrLoadData, tmp);     //nächste Zeile Laden
        
        for (int k = 0; k < m_GridSize; k++)
        {
            if (j == vecLineList[k])
            {
            //Zeile auseinandernehmen und Daten Setzen

                 //Trennstrich Position ermitteln -> anstatt meiner "manuellen" Suche
        SlashPosFirst = tmp.find("/", 0);
        SlashPosSecond = tmp.find("/", SlashPosFirst + 1);
                    
    
            //Ausgelesene Werte Zuweisen
        fTmpH = std::stof(tmp.substr(0, SlashPosFirst));
        fTmpU = std::stof(tmp.substr(SlashPosFirst + 1, SlashPosSecond - SlashPosFirst - 1));
        fTmpBx = std::stof(tmp.substr(SlashPosSecond + 1, tmp.length() - SlashPosSecond - 1));
        Q.push_back(Vector2D(fTmpH, fTmpH*fTmpU));
        Bx.push_back(fTmpBx);

        k = m_GridSize; //For-Schleife vorzeitig verlassen,  da andere Werte nicht mehr geprüft werden müssen
        }//if(j == vecLineList[k]) - passende Zeile gefunden
    }//for (int k = 0; k < m_GridSize; k++)         
}//while (!fstrLoadData.eof())

fstrLoadData.close();



Im letzteren Fall solltest Du Dich unbedingt damit beschäftigen.

Den Debugger werde ich mir zeitnah auf jedenfall vornehmen.


Ich würde allerdings mal raten, dass die ganzen substring-Aufrufe das Problem sind.

Die waren es nicht - habe ich unverändert gelassen, trotzdem danke!

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

9

13.01.2015, 16:55


Im letzteren Fall solltest Du Dich unbedingt damit beschäftigen.

Den Debugger werde ich mir zeitnah auf jedenfall vornehmen.

Wieso nicht gleich, hast ja gerade eine wunderbare Chance, damit anzufangen? ;)
Jede Sekunde, die du ohne Debugger verbringst, ist eine Sekunde zu viel. Der Debugger ist für einen Programmierer in etwa so wichtig wie die Luft zum Atmen...

10

31.01.2015, 15:01


Wieso nicht gleich, hast ja gerade eine wunderbare Chance, damit anzufangen? ;)
Jede Sekunde, die du ohne Debugger verbringst, ist eine Sekunde zu viel. Der Debugger ist für einen Programmierer in etwa so wichtig wie die Luft zum Atmen...


Meine Ausrede hängt mit dem akuten Zeitmangel zusammen, der mit meiner Abschlussarbeit einher geht :-) Habe mir aber die Grundlagen mal explizit angeschaut und gemerkt, dass ich für die Fehlersuche schon die ganze Zeit ne Mischung aus Fehlersuche mit Konsole und Debugger verwendet habe. :thumbsup:

Werbeanzeige