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

02.12.2006, 12:19

Klassenproblem,

Hallo,

ich hab ein sehr merkwürdiges problem und komm einfach nicht dahinter:

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

// //////////////////////              Get Item         ////////////////////

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

// purpose :  - Give Item to Hero

void CHero::GetItem(CItem *Item)
{
    // Variables

    char cChangeEquippment, cWhichItem;
    int iItemType = 0, iRingsAnkhs = 0;
    bool bRemoved = false;

    if (Item->bEquippment == true)
    {
        // Equippment

        if (Item->bStaff == true)
            iItemType = 0;
        else if (Item->bCap == true)
            iItemType = 1;
        else if (Item->bCloak == true)
            iItemType = 2;
        else if (Item->bArmor == true)
            iItemType = 3;
        else if (Item->bRing == true)
            iItemType = 4;
        else if (Item->bAmulet == true)
            iItemType = 8;
        else
            iItemType = 9;

        if (Equippment[iItemType]->stName != "Nichts" && (Item->bRing == false && Item->bAnkh == false))
        {
            // Change Item

            cout << "Ihr tragt bereits einen Gegenstand dieses Typs:" << endl;
            Equippment[iItemType]->ShowStats();
            cout << "Durch neuen Gegenstand ersetzen : (j)a, (n)ein" << endl; 
            cin >> cChangeEquippment;
            if (cChangeEquippment == 'j' || cChangeEquippment == 'J')
            {
                RemoveItem(iItemType, Item);
                bRemoved = true;
            }   
//...

    if (bRemoved == false)
        {
            
            Equippment[iItemType] = Item;
            
            // Modify Stats of Hero

            iStrength += Equippment[iItemType]->Bonus_iStrength;
            iAgility += Equippment[iItemType]->Bonus_iAgility;
            iVitality += Equippment[iItemType]->Bonus_iVitality;
            iSpellpointsMAX = Equippment[iItemType]->Bonus_iSpellpoints;
            iSpellpoints = iSpellpointsMAX;
            fArmor += Equippment[iItemType]->Bonus_fArmor;
            iHitpointsMAX += Equippment[iItemType]->Bonus_iHitpointMax;
            iMantora += Equippment[iItemType]->Bonus_iMantora;
            iDamageNORMAL += Equippment[iItemType]->Bonus_iDamageNORMAL;
            iDamageNATURE += Equippment[iItemType]->Bonus_iDamageNATURE;
            iDamageFIRE += Equippment[iItemType]->Bonus_iDamageFIRE;                        
            iDamageWATER += Equippment[iItemType]->Bonus_iDamageWATER;
            iDamageLIGHT += Equippment[iItemType]->Bonus_iDamageLIGHT;
            iDamageDARKNESS += Equippment[iItemType]->Bonus_iDamageDARKNESS;    
            iResistanceNATURE += Equippment[iItemType]->Bonus_iResistanceNATURE;
            iResistanceFIRE += Equippment[iItemType]->Bonus_iResistanceFIRE;        
            iResistanceWATER += Equippment[iItemType]->Bonus_iResistanceWATER;                                                                  
            iResistanceLIGHT += Equippment[iItemType]->Bonus_iResistanceLIGHT;
            iResistanceDARKNESS += Equippment[iItemType]->Bonus_iResistanceDARKNESS;
        }
// ...

// end Get Item




C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
// //////////////////////////////////////////////////////////////////////////

// ////////////////////            Remove Item         ///////////////////

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

// purpose :  - Remove Item from Hero

void CHero::RemoveItem(int iEquippmentType, CItem *Item)
{
    delete Equippment[iEquippmentType];
    Equippment[iEquippmentType] = new CItem;
    GetItem(Item);
}


also gibt nicht viel zu sagen, der funktion get item wird ein pointer auf eine klasse CItem übergeben. Der Held zieht das Item an und falls er einen gegenstand schon besitzt von dem typ kann er ihn auswechseln oder nicht.
wenn er wechseln will removed es ihm den gegenstand und er bekommt das neue item angezogen.


jetzt ist folgendes:

der held bekommt nen stab mit z.b. 5 schaden.
er zieht ihn an und funktioniert alles perfekt.
jetzt findet er nen stab mit 20 schaden und er wird gefragt ob er den alten stab wechseln will. um zu zeigen welcher stab besser ist wird die ShowStats funktion vom getragenen gegenstand aufgerufen und da liegt das problem.

es zeigt nen stab mit 20 schaden an, also das Equippment[0] (Stab) wird also schon vorher überschrieben oO

wie kann da sein ? wo ist denn hier der fehler?

bitte um hilfe, weil ich ehrlich nicht draufkomme, habs schon sooft jetzt durchgegangen von oben nach unten und ich komm ned drauf :(


mfg
Drac

edit: achja bei der remov itemfunktion sieht man mal

Equippmentblabla = new CItem;

CItem ist einfach der standardkonstruktor der einen leeren gegenstand erzeugt mit dem Namen Nichts.

grek40

Alter Hase

Beiträge: 1 491

Wohnort: Dresden

  • Private Nachricht senden

2

02.12.2006, 13:09

Weiß nich, ob es mit dem Fehler zu tun hat, aber du kopierst nicht das übergebene Item in den Charakter sondern fügst einfach den Pointer ein:

C-/C++-Quelltext

1
Equippment[iItemType] = Item;


1: Du produzierst nen Speicherleck (soweit ich das sehe), da dein new CItem überschrieben wird
2: Wenn du das übergebene Item änderst ändert sich auch das Item im Hero
3: Wenn Item eher zerstört wird als es soll gibt es sowieso Ärger

3

02.12.2006, 14:00

daran liegts irgendwie auch ned, aber hab das sogar übersehen danke :)

der memory leak ist jetzt nicht mehr vorhanden fehler ist aber der gleiche :(

irgendwie wird bei der übergabe des CItem *Item automatisch shcon das Equippment überschrieben... und das check ich absolut ned, weil das nirgends im code vorkommt außer ganz unten eben dann.

bei der abfrage , ob man we1chseln will oder nicht passiert mit dem Equippment absolut gar nichts und trotzdem wird es automatisch zum übergebenen item gemorpht :(

edit: vl sollte ich auch noch erwähnen,dass Equippment ein teil von der klasse CHero ist.

*Equippment[11];

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

4

02.12.2006, 14:10

kann es sein, dass das überschreiben schon außerhalb dieser funktionen passiert. ich find nämlich nicht wirklich was in dem code, das dazu führen könnte...

C-/C++-Quelltext

1
Equippment[iItemType]->stName


von welchem typ ist das?
char* oder std::string?

ich hoffe, dass es letzteres ist. sonst würde:

C-/C++-Quelltext

1
2
3
if (Equippment[iItemType]->stName != "Nichts" && (Item->bRing == false && Item->bAnkh == false))
        {
            // Change Item


praktisch immer aufgerufen werden, solang es kein ring oder amulett ist...

achja, ich denk nicht, dass ein item ring und stab gleichzeitig sein kann oder?
wenn nicht, dann wärs sicher eine überlegung wert, einfach den itemType direkt im item zu speichern, anstatt einen bool und dann diese if abfragen zu machen ;)

5

02.12.2006, 20:01

ist vom typ string :) char* find ich irgendwie bischen umständlicher und damit funktionieren die string funktionen (append, find, ...) nicht oder?


und nein es kommt immer nur 1 item nach dem anderen rein.

also entweder stab ODER kappe ODER umhang ...

aber es gibt keinen ringstab, oder amulettringstab. sowas existiert nicht :)

hier der aufruf der funktion

C-/C++-Quelltext

1
2
3
CItem *Item = new CItem(5,false,false,false);
Hero->GetItem(Item);
delete Item;


CItem(int, bool, bool, bool) ist eine funktion was einen gegenstand mit zufälligen werten einfach kreiert.

der int wert ist das level des items (also sozusagen die staerke).
dann folgen 2 bool werte obs ein magischer oder ein seltener gegenstand sein soll und der letzte bool wert ist, ob es ein equippment sein soll oder eben nicht (z.b. ein trank oder schriftrolle oder so).

hier seh ich eben auch das problem eigentlich nicht, warum so "morphhafte" fehler auftreten :(

sehr merkwürdig das ganze :)

grek40

Alter Hase

Beiträge: 1 491

Wohnort: Dresden

  • Private Nachricht senden

6

02.12.2006, 23:08

Sicher, dass jetzt das ganze Item ordentlich kopiert wird?

Ansonsten wär es auch mal interessant, an welchem Punkt die Werte auf die ShowStats zugreift vom alten auf den neuen Gegenstand wechseln -> gekonnter Einsatz vom Debugger müsste helfen.

7

02.12.2006, 23:43

der verursacht irgendeinen fehler,den ich ned abcheck, deswegen nutzt der irgendwie nix leider :)

und das item wird ordentlich kopiert sonst würde es ja mit den ersten stab den man bekommt ja nicht klappen und mit dem klappts fehlerfrei :)

es klappt mit allen items fehlerfrei, nur eben wenn man 2 vom selben typ hat, gibts merkwürdige ergebnisse, die einfach nicht sein können, weil der code ja anscheinend fehlerfrei ist :)

grek40

Alter Hase

Beiträge: 1 491

Wohnort: Dresden

  • Private Nachricht senden

8

03.12.2006, 01:07

Versuch mal folgendes:
Überwachung hinzufügen für Equippment[type] mit type alle für den Fehler relevanten. Wenn du dann noch nen Haltepunkt an den Anfang der kopierfunktion setzt hast du mMn. schonmal die Voraussetzungen.

Jetzt zuerst checken, ob Equippment in diesem Moment noch richtig ist oder schon falsche Werte hat, dann per F10 durchgehen. Wenn eine Variable in der Überwachung verändert wird müsste das direkt dannach rot gekennzeichnet sein. Änderungen immer überprüfen, ob sie den Erwartungen entsprechen oder nicht. im Umgang mit Pointern auch immer neben den Werten checken, ob ausversehen auch die Adressen gleich sind.

9

03.12.2006, 13:35

hm k danke "wir" sind dem problem auf der spur :)

hab jetzt folgendes rausgefunden.

die funktion wird zu beginn gleich mal so aufgerufen um dem held einen stab in die hand zu geben.

C-/C++-Quelltext

1
2
3
Item = new CItem("BasicWand");
Hero->GetItem(Item);
delete Item;


und jetzt , wenn die funktion nochmal aufgerufen wird, ist das Equippment[0] (also der stab) irgendwie mit fehlern behaftet :( nämlich:

das Equippment[0] ist gar nichts mehr und wird eben mit irgendwelchen werten initialisiert.

namen keinen
float wert für armor ist irgendein hexadezimalwert.
die boolwerte sind irgendwas und die integerwerte sind - 5millionen oder sowas.

jetzt stellt sich wiederum die frage warum, das equippment gelöscht wird oO sowas steht ja auch nirgends im code :(

edit: so ich hab das problem :)

wenn die funktion beendet wird, wird das übergebene CItem *Item ja deletet und somit ist der pointer *Equippment[0] auch für nichts mehr zu gebrauchen, weil er an der adresse von *Item nichts mehr findet.

ich muss also schauen, dass der irgendwie ne eigene Adresse bekommt, dass der durch das deleten des Items nicht beeinflusst wird :)



danke für die tipps =)

grek40

Alter Hase

Beiträge: 1 491

Wohnort: Dresden

  • Private Nachricht senden

10

03.12.2006, 13:57

Das bestätigt meine Vermutung, dass du das Item innerhalb von GetItem immernoch nicht ordentlich kopierst. Zeig mal bitte, wie

C-/C++-Quelltext

1
2
3
4
if (bRemoved == false)
{
    Equippment[iItemType] = Item;
    // ...

aktuell aussieht und dann den entsprechenden Copy-operator (oder die Copy Funktion)

// @Neues Problem: ganz Easy^^

Ich schreib gleich ma was dazu

Werbeanzeige