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

28.01.2015, 15:49

[VC++] Debugger - Unbehandelte Ausnahme (msvcr110d.dll) ; Zugriffsverletzung beim Schreiben

Hallo,

während ich versucht habe Klassenvektoren in Dateien zu speichern und zu laden, ist mir beim Debuggen mein Programm abgestürzt und dieser Fehler aufgetreten:
Unbehandelte Ausnahme bei 0x0F210E9A (msvcr110d.dll) in RPG_Battle_Arena.exe: 0xC0000005: Zugriffsverletzung beim Schreiben an Position 0x00FCA508

Witzig dabei ist, dass der Vektor korrekt geladen wird, jedoch nicht die Vektordaten und mir das Programm beim allerersten Durchgang (ohne Debugger) erst bei ca.Zeile 124 abgestürzt ist aber danach immer wieder bei Zeile 47.

Der Code:

main.cpp

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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#include "Entity.hpp"

using namespace std;

void Game(bool *error, vector<Attack> vector_list);
void AttackEditor(bool *error, vector<Attack> &vector_list);

int main()
{   
    bool error;
    int input;
    
    vector<Attack> attack_list;
    
    cout<<"BATTLE ARENA SYSTEM v0.1"
        <<"\n\n\nWhat are you gonna do?"
        <<"\n1. Play"
        <<"\n2. Edit Attacks"
        <<"\nPlease enter a number: ";
    cin>>input;
    
    switch (input)
    {
    case 1:
        Game(&error, attack_list);
        break;
    case 2:
        AttackEditor(&error, attack_list);
        break;
    default:
        break;
    }
    cout<<endl;
    return 0;
}

void Game(bool *error, vector<Attack> vector_list)
{
    *error = false;
    while(*error == false)
    {
        ifstream input("Attack_List.cfd");
        if(input.is_open() == false){cout<<"Failed to open: Attack_List.cfd"; *error = true; break;}
        cout<<"Loading files...\n";
        input.read((char *) &vector_list, sizeof(vector_list));
        //In der nächsten Zeile hakt es...
        for(int i=0;i<static_cast<int>(vector_list.size());i++){input.read((char *) &vector_list[i], sizeof(vector_list[i]));}
        //Das Programm ist abgestürzt; beim Debuggen taucht der Fehler auf:
        //Unbehandelte Ausnahme bei 0x0FD70E9A (msvcr110d.dll) in RPG_Battle_Arena.exe: 0xC0000005: Zugriffsverletzung beim Schreiben an Position 0x00FCA508
        cout<<"Sucessfully loaded files.\n";
        input.close();
        break;
    }
    
    Entity Player("Pwalb", 1250, 64, 600);
    Entity Enemy("Danarius", 24000, 0, 300);

    srand (time(NULL));
    int input;
    
    cout<<"\n"<<Player.get_name()<<" - HP: "<<Player.get_int("e_curHP")<<", MP: "<<Player.get_int("e_curMP")
        <<"\n"<<Enemy.get_name()<<" - HP: "<<Enemy.get_int("e_curHP");
    do{     
        //Player's turn
        cout<<"\n\nWhat are you gonna do?: ";
        cout<<"\n0. Quit";
        cout<<"\n1. Attack";
        cout<<"\n2. Heal";
        cout<<"\n3. Energy Beam";
        cout<<"\nPlease enter a number: ";
        cin>>input;

        switch(input)
        {
        case 0:
            cout<<"\nGame is closing...";
            break;
        case 1:
            Player.cast_skill(vector_list[0], Enemy);
            break;
        case 2:
            Player.cast_skill(vector_list[1], Player);
            break;
        case 3:
            Player.cast_skill(vector_list[2], Enemy);
            break;
        default:
            cout<<"\nInvalid input, try again!";
            continue;
        }
        if(input == 0){break;}
        if(Player.get_int("e_curHP") > Player.get_int("e_maxHP")){Player.set_stats(Player.get_int("e_maxHP"), Player.get_int("e_curMP"), Player.get_int("e_attack_damage"));}
        
        if(Player.get_int("e_curHP") <= 0)
        {
            Player.set_stats(0, Player.get_int("e_curMP"), Player.get_int("e_attack_damage"));
            cout<<"\n\nYou died! "<<Enemy.get_name()<<" wins the fight!";
            input = 0;
        }
        if(Enemy.get_int("e_curHP") <= 0)
        {   
            Enemy.set_stats(0, Enemy.get_int("e_curMP"), Enemy.get_int("e_attack_damage"));
            cout<<"\n\n"<<Enemy.get_name()<<" died! You win the fight!";
            input = 0;
        }
        if(input == 0){break;}
        
        //Boss's turn

        Enemy.cast_skill(vector_list[0], Player);

        if(Player.get_int("e_curHP") <= 0)
        {
            Player.set_stats(0, Player.get_int("e_curMP"), Player.get_int("e_attack_damage"));
            cout<<"\n\nYou die! "<<Enemy.get_name()<<" wins the fight!";
            input = 0;
        }
        if(Enemy.get_int("e_curHP") <= 0)
        {   
            Enemy.set_stats(0, Enemy.get_int("e_curMP"), Enemy.get_int("e_attack_damage"));
            cout<<"\n\n"<<Enemy.get_name()<<" die! You win the fight!";
            input = 0;
        }
        //Ab hier ist es das erste mal abgestürzt, danach nie wieder
        cout<<"\n\n"<<Player.get_name()<<" - HP: "<<Player.get_int("e_curHP")<<", MP: "<<Player.get_int("e_curMP")
            <<"\n"<<Enemy.get_name()<<" - HP: "<<Enemy.get_int("e_curHP");
        }while(input != 0);
}

void AttackEditor(bool *error, vector<Attack> &vector_list)
{
    *error=false;
    
    Attack *temp = NULL;
    temp = new Attack("Attack", 1.0f, 0.2f, 0);
    vector_list.push_back(*temp);
    temp = new Attack("Heal", -1.0f, 0.1f, 6);
    vector_list.push_back(*temp);
    temp = new Attack("Energy Beam", 4.0f, 0.2f, 4);
    vector_list.push_back(*temp);   

    cout<<sizeof(vector_list)<<endl
        <<sizeof(vector_list[0])<<endl
        <<sizeof(vector_list[1])<<endl
        <<sizeof(vector_list[2])<<endl
        <<vector_list.size()<<endl;

    while(*error == false)
    {
        ofstream output("Attack_List.cfd");
        if(!output.is_open()){cout<<"Failed to open: Attack_List.cfd"; *error = true; break;}
        cout<<"Saving files...\n";
        output.write((char *) &vector_list, sizeof(vector_list));
        for(int i=0;i<static_cast<int>(vector_list.size());i++){output.write((char *) &vector_list[i], sizeof(vector_list[i]));}
        cout<<"Sucessfully saved files.\n";
        output.close();
        break;
    }
}


(Ich denke, dass Entity.hpp und Entity.cpp nicht imt dem Fehler zu tun haben.)

Beim Speichern geht alles in Ordnung und die Sache dass es beim ersten Mal sogar fast funktioniert hat beweist mir, dass die Vektordaten

Ich habe keine Ahnung was es damit auf sich hat, und wüsste gerne wie ich diesen Fehler löse.
Danke schonmal für eine Antwort!

MfG
Pwalb

Schrompf

Alter Hase

Beiträge: 1 470

Wohnort: Dresden

Beruf: Softwareentwickler

  • Private Nachricht senden

2

28.01.2015, 16:06

Du schreibst den vector selbst und alle Elemente darin binär auf die Platte. Was ein "Attack" ist, weiß ich nicht, aber ein vector ist nicht viel mehr als ein paar Zeiger. Zeiger sind Adressen von allokiertem Speicher. Wenn Du die Adresse speicherst und beim nächsten Programmstart wieder lädst, wird die Adresse der Zahl nach rekonstruiert, aber nicht die Allokation, auf die der Zeiger ursprünglich gezeigt hat. Bitte speichere nur elementare Datentypen wie int oder float mittels read() oder write();

Der Rest des Codes enthält auch noch einige Aua-Momente, aber das kommt später.
Häuptling von Dreamworlds. Baut aktuell an nichts konkretem, weil das Vollzeitangestelltenverhältnis ihn fest im Griff hat. Baut daneben nur noch sehr selten an der Open Asset Import Library mit.

3

28.01.2015, 16:10

Objekte roh byte für byte zu speichern ist eine schlechte Idee. Du solltest nur PODs (also eingebaute datentypen) roh schreiben.

4

28.01.2015, 17:50

Du schreibst den vector selbst und alle Elemente darin binär auf die Platte. Was ein "Attack" ist, weiß ich nicht, aber ein vector ist nicht viel mehr als ein paar Zeiger. Zeiger sind Adressen von allokiertem Speicher. Wenn Du die Adresse speicherst und beim nächsten Programmstart wieder lädst, wird die Adresse der Zahl nach rekonstruiert, aber nicht die Allokation, auf die der Zeiger ursprünglich gezeigt hat. Bitte speichere nur elementare Datentypen wie int oder float mittels read() oder write();

Der Rest des Codes enthält auch noch einige Aua-Momente, aber das kommt später.


Ich dachte man muss ios::binary in das fstream schreiben damit es binär gespeichert wird. Attack ist eine Klasse, ich schrieb dass ich Klassenvektordaten speichern und laden wollte. Außerdem weiß ich nicht wie ich in einer besseren Weise Objekte in Vektoren speichern und laden soll.

FSA

Community-Fossil

  • Private Nachricht senden

5

29.01.2015, 08:51

Stichwort Serialisierung.

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

6

29.01.2015, 11:22

Lass dir mal den Wert von sizeof(vector_list) ausgeben.
Du wirst feststellen, dass dieser sich überhaupt nicht ändert, egal wie viele Elemente du in deinen Vektor packst. Der Wert ist nämlich konstant.

Auch hättest du mal die erzeugte Datei mit einem Text-/Hex-Editor öffnen können. Da hättest du misstrauisch werden müssen, wenn du gesehen hättest, dass dort viel zu wenig drin steht, und dass du auch deine Strings dort nicht findest.

Na, wie könnte man denn eine Liste speichern?
Was macht eine Liste aus?
Wie würdest du jemandem eine Liste am Telefon durchgeben? Da würdest du ja auch nicht sagen "Die Liste liegt hier auf dem Tisch!", denn damit könnte dein Gesprächspartner nichts anfangen.

Werbeanzeige