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

Firefly

Alter Hase

  • »Firefly« ist der Autor dieses Themas

Beiträge: 484

Wohnort: Irgendwoundnirgendwo

  • Private Nachricht senden

1

20.12.2007, 15:24

Liste in Liste - Wo liegt der Fehler?

Hallo Community!
In der letzten Zeit beschäftige ich mich damit einen INI-Reader zusammen zu basteln. Hierfür nutze ich Strukturen welche aus Listen(eigene Listenklasse) welche wiederum Listen enthalten bestehen. Seltsamerweise passiert folgendes: Erstelle ich ein neues Element der Struktur STest(welche eine Liste von DWORDs beinhaltet), füge dieser Inhalt hinzu und möchte nun diese einer Liste von STests übergeben wird in der Liste von dem STest Element die Anzahl der Einträge auf 0 gesetzt obwohl dieser Wert vorher in dem Beispiel 2 beträgt. Hat jemand eine Idee woran es liegen könnte?
Hier zuerst einmal der Quellcode...

C-/C++-Quelltext

1
2
3
4
5
//Die Teststruktur

struct STest
{
    CList<DWORD> DWords;
};

Testabschnitt:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
//Testzyklus

    CList<STest> Tests;
    STest Test;
    DWORD x= 10;
    Test.DWords.AddEntry(&x);
    x = 20;
    Test.DWords.AddEntry(&x);
    Tests.AddEntry(&Test);

und sollte es an der Klasse liegen hier die klasse

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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
//Eintragsstruktur

template<typename Type> struct SListEntry
{
    SListEntry<Type> *pNextEntry;   //Nächster Eintrag

    SListEntry<Type> *pPrevEntry;   //vorheriger Eintrag

    Type              Data;         //Daten

};
//***************************************************************************************//

template<typename Type> class CList
{
private:
    SListEntry<Type> *m_pFirstEntry;        //Erster Eintrag

    SListEntry<Type> *m_pLastEntry;         //Zweiter Eintrag

    DWORD             m_dwNumListEntries;   //Anzahl Einträge

public:
    //Konstruktor

    CList(): m_dwNumListEntries(0), m_pFirstEntry(NULL), m_pLastEntry(NULL) {}
    //Destruktor

    ~CList();
    //Methoden

    SListEntry<Type>*   AddEntry(Type *pData);
    auResult            FindEntry(Type *pData, SListEntry<Type>** ppOut);
    auResult            DeleteEntry(SListEntry<Type>* pEntry);
    auResult            Clear(void);
    auResult            UpdateNumEntries(void);
    //Abfragefunktionen

    SListEntry<Type>*   GetEntry(DWORD dwIndex);
    Type                GetEntryData(DWORD dwIndex);
    Type                GetEntryData(SListEntry<Type> *pEntry)  {return &pEntry->Data;}
    DWORD               GetNumEntries(void)                     {return m_dwNumListEntries;}
    SListEntry<Type>*   GetFirstEntry(void)                     {return m_pFirstEntry;}
    SListEntry<Type>*   GetLastEntry(void)                      {return m_pLastEntry;}
};
//***************************************************************************************//

template<typename Type> CList<Type>::~CList()
{
    //alle Einträge löschen

    Clear();
}
//***************************************************************************************//

template<typename Type> SListEntry<Type>* CList<Type>::AddEntry(Type *pData)
{
    SListEntry<Type> *pNewEntry;
    //Speicher reservieren

    pNewEntry = new SListEntry<Type>;
    //letzten Eintrag als Vorgänger des neuen Eintrags anlegen

    pNewEntry->pPrevEntry = m_pLastEntry;
    if(m_pLastEntry)m_pLastEntry->pNextEntry = pNewEntry;
    pNewEntry->pNextEntry = NULL;
    m_pLastEntry = pNewEntry;
    //testen ob erster Eintrag existiert, wenn nicht pNewEntry zu erstem EIntrag machen

    if(!m_pFirstEntry)m_pFirstEntry = pNewEntry;
    //Daten kopieren

    memcpy(&pNewEntry->Data, pData, sizeof(pData));
    //Einträgezähler erhöhen

    m_dwNumListEntries++;
    //Zeiger zurückgeben

    return pNewEntry;
}
//***************************************************************************************//

template<typename Type> auResult CList<Type>::FindEntry(Type *pData, SListEntry<Type>** ppOut)
{
    CListEntry<Type> *pCurrentEntry;
    //prüfen ob Daten zulässig

    if(!pData)return E_FAIL;
    //erster Eintrag

    pCurrentEntry = m_pFirstEntry;
    //Liste durchgehen solange EIntrag gültig

    while(pCurrentEntry)
    {
        //Speicherbereich vergleichen

        if(!memcmp(pCurrentEntry->Data, pData, sizeof(pData)))
        {
            //ausgeben

            if(ppOut)*ppOut = pCurrentEntry;
            //abbrechen

            return AU_OK_FOUND;
        }
        //nächster Eintrag

        pCurrentEntry = pCurrentEntry->pNextEntry;
    }
    //nichts gefundne

    return AU_ERRR_NOT_FOUND;
}
//***************************************************************************************//

template<typename Type> auResult CList<Type>::DeleteEntry(SListEntry<Type>* pEntry)
{
    //Parameter gültig?

    if(!pEntry)return AU_ERROR_PARAMETER;
    //testen ob gleichzeitig 1. und letzter Eintrag

    if(pEntry == m_pFirstEntry && pEntry == m_pLastEntry)
    {
        //auf NULL setzen

        m_pFirstEntry = NULL;
        m_pLastEntry  = NULL;
    }
    //testen ob nur 1. Eintrag

    else if(pEntry == m_pFirstEntry)
    {
        //nächster Eintrag = neuer erster Eintrag

        m_pFirstEntry = pEntry->pNextEntry;
        //auf NULL setzen

        m_pFirstEntry->pPrevEntry = NULL;
    }
    //testen ob letzter Eintrag

    else if(pEntry == m_pLastEntry)
    {
        //vorheruiger Eintrag = letzter Eintrag

        m_pLastEntry = pEntry->pPrevEntry;
        //auf NULL setzen

        m_pLastEntry->pNextEntry = NULL;
    }
    //Eintrag irgendwo in der Mitte

    else
    {
        //verknüpfen

        pEntry->pPrevEntry->pNextEntry = pEntry->pNextEntry;
        pEntry->pNextEntry->pPrevEntry = pEntry->pPrevEntry;
    }
    //Speicher freigeben

    delete pEntry;
    //Zähler dekrementieren

    m_dwNumListEntries--;
    //alles ok

    return AU_OK;
}
//***************************************************************************************//

template<typename Type> auResult CList<Type>::Clear(void)
{
    //Liste durchgehen und solange 1. Eintrag existiert löschen

    while(m_pFirstEntry)DeleteEntry(m_pFirstEntry);
    //Alles ok

    return AU_OK;
}
//***************************************************************************************//

template<typename Type> SListEntry<Type>* CList<Type>::GetEntry(DWORD dwIndex)
{
    CListEntry<Type> *pCurrentEntry;
    DWORD             dwCount = 0;
    //auf ersten Eintrag setzen

    pCurrentEntry = m_pFirstEntry;
    //Liste durchgehen

    while(dwCount != dwIndex)
    {
        //erhöhen solange ungleich

        if(pCurrentEntry)pCurrentEntry = pCurrentEntry->pNextEntry else return NULL;
        dwCount++;
    }
    //zurückgeben

    return pCurrentEntry;
}
//***************************************************************************************//

template<typename Type> Type CList<Type>::GetEntryData(DWORD dwIndex)
{
    SListEntry<Type> *pCurrentEntry;
    DWORD             dwCount = 0;
    //auf ersten Eintrag setzen

    pCurrentEntry = m_pFirstEntry;
    //Liste durchgehen

    while(dwCount != dwIndex)
    {
        //erhöhen solange ungleich

        if(pCurrentEntry)pCurrentEntry = pCurrentEntry->pNextEntry; else return NULL;
        dwCount++;
    }
    //zurückgeben

    return pCurrentEntry->Data;
}
//***************************************************************************************//

template<typename Type> auResult CList<Type>::UpdateNumEntries(void)
{
    SListEntry<Type>    *pCurrentEntry;
    DWORD               dwEntries = 0;
    //auf ersten Eintrag setzen

    pCurrentEntry = m_pFirstEntry;
    //Liste durchgehen

    while(pCurrentEntry)
    {
        //nächster Eintrag

        pCurrentEntry = pCurrentEntry->pNextEntry;
        //erhöhen

        dwEntries++;
    }
    //übertragen

    m_dwNumListEntries = dwEntries;
    //Alles ok;

    return AU_OK;
}

Danke im voraus schon mal für alle Antworten!!!

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

2

20.12.2007, 15:30

Dir fehlen ein gescheiter Kopierkonstruktor sowie ein zuweisungs Operator.
@D13_Dreinig

3

20.12.2007, 15:55

Naja ich mag deinen Codingstyle net ^^ Aber was solls ... beachte die Regel der Großen 3 und fertig.
Devil Entertainment :: Your education is our inspiration
Der Spieleprogrammierer :: Community Magazin
Merlin - A Legend awakes :: You are a dedicated C++ (DirectX) programmer and you have ability to work in a team? Contact us!
Siedler II.5 RttR :: The old settlers-style is comming back!

Also known as (D)Evil

Firefly

Alter Hase

  • »Firefly« ist der Autor dieses Themas

Beiträge: 484

Wohnort: Irgendwoundnirgendwo

  • Private Nachricht senden

4

20.12.2007, 16:02

danke erstmal für die antworten

@David_pb: Was wäre denn für dich ein gescheiterter Konstruktor? Einer der Speicher für m_pFirstEntry und m_pLastEntry allokiert und nicht einfach nur die Elemente auf NULL setzt?

@Deviloper: Du musst meinen Codingstyle auch nicht mögen...was sollen denn diese Regeln der Großen 3 sein?

5

20.12.2007, 16:06

Die regel der Großen 3? Guck halt bei google oder yahoo "C++ big three"

C-/C++-Quelltext

1
2
3
4
5
6
7
CList& operator=(CList const& rhs)
{
    if (this == &rhs) return *this;
    // ...

}
CList(CList const& rhs);
CList();
... implementiere die und fertig ...


http://www.artima.com/cppsource/bigtwo.html
http://en.wikipedia.org/wiki/Rule_of_three_(C%2B%2B_programming)


Fast vergessen ... struct entspricht in c++ class, bis auf, dass struct default-access public hat. class private.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
struct foo
{ int var; };
// == 

class foo
{ public: int var; };

struct bar
{private: int var; };
// == 

class bar
{ int var; };

struct und class haben beide einen Konstruktor, Destruktor. Beide können Funktionen und Variablen haben sowie Operatoren.
Devil Entertainment :: Your education is our inspiration
Der Spieleprogrammierer :: Community Magazin
Merlin - A Legend awakes :: You are a dedicated C++ (DirectX) programmer and you have ability to work in a team? Contact us!
Siedler II.5 RttR :: The old settlers-style is comming back!

Also known as (D)Evil

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

6

20.12.2007, 16:35

Zitat von »"Firefly"«


@David_pb: Was wäre denn für dich ein gescheiterter Konstruktor? Einer der Speicher für m_pFirstEntry und m_pLastEntry allokiert und nicht einfach nur die Elemente auf NULL setzt?


Ich sprach von Kopierkonstruktor! Einer der dein Objekt in die tiefe kopiert und nicht nur eine flache Kopie erstellt!
Und irgendwie drängt sich die Frage auf: Wieso verwendest du nicht einfach std::list<>?
@D13_Dreinig

Firefly

Alter Hase

  • »Firefly« ist der Autor dieses Themas

Beiträge: 484

Wohnort: Irgendwoundnirgendwo

  • Private Nachricht senden

7

20.12.2007, 18:06

gut hab ich jetzt implementiert, problem besteht allerdings immer noch...

8

20.12.2007, 18:15

Dann zeig implementierung ... aja und std::memcpy bei einer Klasse? ok ... ^^
Devil Entertainment :: Your education is our inspiration
Der Spieleprogrammierer :: Community Magazin
Merlin - A Legend awakes :: You are a dedicated C++ (DirectX) programmer and you have ability to work in a team? Contact us!
Siedler II.5 RttR :: The old settlers-style is comming back!

Also known as (D)Evil

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

9

20.12.2007, 18:38

Zitat von »"Firefly"«

gut hab ich jetzt implementiert, problem besteht allerdings immer noch...


Tu dir selbst einen Gefallen und verwend doch was Funktionsfähiges, Vorhandenes! (--> std::list<>)
@D13_Dreinig

10

20.12.2007, 18:52

Zitat

Tu dir selbst einen Gefallen und verwend doch was Funktionsfähiges, Vorhandenes! (--> std::list<>)


Wenn er doch aus Übungszwecken ne eigene Klasse implementieren will dann kann er das doch ruhig tun und da er die Goldene 3er Regel noch nicht gekannt hat und sie jetzt kennt hat er doch dabei schonmal was wichtiges gelernt!
Das Böse ist des Menschensbeste Kraft - Friedrich Nietzsche

Werbeanzeige