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

grek40

Alter Hase

Beiträge: 1 491

Wohnort: Dresden

  • Private Nachricht senden

11

03.12.2006, 14:06

Das Problem ist ja im Wesentlichen

C-/C++-Quelltext

1
Equippment[iItemType] = Item;

Damit jetzt nicht nur der Zeiger kopiert muss da was kleines geändert werden. Es gibt grundlegend erstmal 2 Möglichkeiten:
1: Immer das neue Item in das alte reinkopieren:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
// Erfordert Copy-operator in CItem

*(Equippment[iItemType])=*Item;

// Copy operator:

CItem& CItem::operator =(const CItem& _copy)
{
  // alle Variablen kopieren...

  return *this;
}

2: Immer das alte Item löschen und ein neues kreieren:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
// Erfordert den Copy-Konstruktor in CItem

delete Equippment[iItemType];
Equippment[iItemType] = new CItem(*Item);

// Copy-Konstruktor:

CItem::CItem(const CItem& _copy)
: _var1(_copy.var1), _var2(_copy.var2) // ... Initialisierungsliste

{
}

12

03.12.2006, 14:18

das wars:)

hab die zweite variante genommen, die klappt :)

danke grek

nur wozu bräuchte ich denn deine copy operators? sind die nicht schon vordefiniert? weil sowas verwend ich nrigendwo in meinem code, weil operatoren doch schon vordefiniert sind oder? :)

grek40

Alter Hase

Beiträge: 1 491

Wohnort: Dresden

  • Private Nachricht senden

13

03.12.2006, 15:28

Naja... der Nachteil von vordefinierten operatoren ist, dass die auch jeden Pointer einfach übernehmen -> da will man ja meist eher den Inhalt kopieren. Ohne Pointer reicht es meist auch ohne = operator aber wenn man sich gleich angewöhnt einen zu implementieren hat man nicht das Problem, dass sich später unbemerkt Fehler einschleichen.

14

03.12.2006, 22:03

k thx :)

sry,dass ich nochmal nerve, aber ich hab noch ein einziges problemchen was ich auch ned ganz verstehe und im google nix dazu gefunden habe.

also folgendes:

ich hab ne lade funktion drinnen, die einen spielstand ladet (einfach die abgepsiecherte figur ladet).

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void Load() 
{ 
    if (Hero != NULL)
        delete Hero; 
  Hero = new CHero; 

  cout << "Spielstand wird geladen." << endl; 
  ifstream Input ("Spielstand.sps", ios::binary); 
  Input.read((char*) &Spielstand, sizeof (Spielstand)); 
  Hero = &Spielstand; 
  Input.close(); 

    Hero->ShowStats();
        
    cout << "\n\nWeiter mit Enter" << endl;
    do {getchar();} while (getchar() != '\n');
} 


das funktioniert auch alles, denn die Show Stats funktion liefert richtige ergebnisse :)

wenn jetzt aber das spiel gestartet wird in der main wie folgt

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int main (void)
{
//...

    do
    {
//...

        cin >> cMenuepoint;
        
        switch (cMenuepoint)
        {
        case('1'):
            {
                //  Start Game

                cout << "Spiel wird gestartet...\n\n\n" << endl;
                // Delete Old Hero Class

                if (Hero != NULL)
                {
                    delete Hero;
                    Hero = NULL;
                }



dann kommt folgender windows fehler.


microsoft visual c++ debug library error

debug assertion failed!

program:......druiden.exe
file:dbgheap.c
line: 1011

Expression:_crtisvalidheappointer(puserdata)




was ist das für ein fehler? liegt das an nem fehler in meinem code oder ist das ein microsoft visual c++ fehler, wegen ner defekten installation oder so?

mfg
Drac

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

15

03.12.2006, 22:18

evtl. wurde Hero nicht mit 0 initialisiert...

16

03.12.2006, 22:54

doch doch eben schon :)

das wundert mich eben.

weil wenn ich es ganz normal durchlaufen lasse funzt es und auch ein regame funktioniert ganz normal, nur wenn ich nen save einlade kommt dieser visual assisst error.

sehr merkwürdig wiedereinmal :)

grek40

Alter Hase

Beiträge: 1 491

Wohnort: Dresden

  • Private Nachricht senden

17

03.12.2006, 23:11

Es ist eigentlich immer der selbe Fehler...

C-/C++-Quelltext

1
Hero = &Spielstand; 


Das ist mal wieder ein Überschreiben des Pointers von Hero und damit ein Speicherleck und außerdem Hero fortan nicht mehr auf den Heap gerichtet.

C-/C++-Quelltext

1
*Hero = Spielstand; 


Sorum muss es gehen um den Inhalt vom Spielstand in den Hero zu bringen ;)

Und nächstes mal bitte nen neues Problem :lol:

koschka

Community-Fossil

Beiträge: 2 862

Wohnort: Dresden

Beruf: Student

  • Private Nachricht senden

18

04.12.2006, 00:10

... du solltest in jeder Klasse, die einen Pointer hat, den Pointer immer als NULL in einem Constructor, Kopiekonstruktor oder irgendeinem anderen setzen.

Hier mal eine Nice Class. Solche Klassen sollte man eigentlich nur schreiben, Nice Classes haben immer (mind.) einen Zuweiungsoperator, einen Standardkonstruktor, Copykonstruktor und einen Destruktor.

Ich glaub du solltest erstmal dieses Beispiel verstehen und mal richtig debuggen (Haltepunkte, Überwachung, etc.)

Beispiel:

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
#include <string>

typedef struct ItemObj
{
  std::string name;   // Namen

  std::string klasse;  // Itemklasse

} ItemObject;


class Hero
{
private:
  // unser Hero kann mehrere Items haben

  ItemObject *Items;
  unsigned Anzahl;
public:
  // Standardkonstruktor

  Hero(void);  
  // Kopierkonstruktor, zuerst Items auf NULL setzen, Compiler machen das

  // nicht automatisch!!!, Zuweisungsoperator dann verwenden

  Hero(Hero& a) { Items = NULL; *this = a; )

  // Zuweisungsoperator, müssen wir deklarieren, da wir mit pointern

  // arbeiten!

  Hero& operator=(Hero& a);

  // Destruktor

  ~Hero(void);
}

Hero::Hero(void) 
{
  Items = NULL;
  Anzahl = 0;
}

Hero& Hero::operator=(Hero& a)
{
   // da wir eine Zuweisung betrachten, erstmal alle löschen!

    if(Items)
      delete[] Items;
    Items = NULL;
    Anzahl = 0;

  // sind in a items?

  if(a.Items)
  {
    // in a sind Items!

    // Anzahl an items kopieren

    Anzahl = a.Anzahl;
    // Speicher für die Items!

    Items = new ItemObject [a.Anzahl];
    if(!Items) { /*zu wenig speicher */ }

    for(unsigned x=0; x < Anzahl; x++)
    {
       // Werte zuweisen, für Strings haben wir den = operator

       Items[x].name = a.Items[x].name;
       Items[x].klasse = a.Items[x].klasse;
    }
  }
  // nix in a... oder Items vereits erfolgreich kopiert


  return *this; // Zurückgeben, wegen Mehrfachzuweisung

}

Hero::~Hero(void) 
{
  if(Items)
    delete[] Items; // wegen Array

  Items = NULL;  // Items auf 0 setzen, damit nicht nochmal der Destr. aufgerufen wird

  Anzahl = 0;
}

19

06.12.2006, 17:25

edit: lol bin ich deppert :D

hat sich erledigt sry^^

20

10.12.2006, 15:37

hm wieder mal ne frage :)

wenn das programm,wennich es mitn debugger durchlaufen lasse schritt für schritt fehlerfrei funktioniert und auch keine fehler und nichts verursacht und ich es dann aber dann normal kompiliere und ausführe, sodass es nicht mehr so "langsam" schritt für schritt durchläuft und genau hier dann fehlre auftreten, worin kann das liegen?


weil es ist halt schwer nen fehler zu finden, der irgendwie nicht da zu sein scheint^^

edit: ah k war ein sehr versteckert fehler.

man darf von nem zeiger, der auf NULL gerichtet ist, keine abfragen machen.

z.B.:

C-/C++-Quelltext

1
2
3
CClass *pPointer = NULL;
if(CClass pPointer->stName == "Irgendeinname")
//...


sowas verursacht nen fehler.

komisch, aber k^^

edi2:

ach noch ne frage genau:

warum tritt bei meiner savegamevariante,was ich vorhergepostet habe folgender fehler auf?

wenn man die konsole offen klässt kann man speichern und laden wie man will, er liest auch die datei immer richtig ein und alles, aber sobald man die konsole schließt und später mal neustartet, kann er plötzlich die datei nicht mehr richtig einlesen und es kommt ein fehler.

warum? :)

mfg
simon

edit3: hm steht doch ned vorher, also hier die 2 funktionen

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
// //////////////////////////////////////////////////////////////////////////

// /////////////////////////               Save        ////////////////////////////

// //////////////////////////////////////////////////////////////////////////

// purpose :  - Save Gamestate

void Save() 
{ 
  //Variables

  CHero *Savegame = NULL;   // SaveClass

  Savegame = new CHero(Hero);

  cout << "Spielstand wird gespeichert." << endl; 
  ofstream Output ("Spielstand.sps" , ios::binary); 
  Output.write((char*) &Savegame, sizeof (Savegame)); 
  Output.close(); 
} // end Save




// //////////////////////////////////////////////////////////////////////////

// /////////////////////////               Load        ////////////////////////////

// //////////////////////////////////////////////////////////////////////////

// purpose :  - Load Gamestate

void Load() 
{ 
  //Variables

  CHero *Savegame = NULL;   // SaveClass

  if (Hero != NULL)
    delete Hero; 
    
  cout << "Spielstand wird geladen." << endl; 
  ifstream Input ("Spielstand.sps", ios::binary); 
  Input.read((char*) &Savegame, sizeof (Savegame)); 
  Hero = new CHero(Savegame); 
  Input.close(); 
    
  Hero->ShowStats();
} // end Load

Werbeanzeige