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

$nooc

Alter Hase

  • »$nooc« ist der Autor dieses Themas

Beiträge: 873

Wohnort: Österreich / Kärnten

Beruf: Schüler

  • Private Nachricht senden

1

09.03.2007, 10:37

verkettete liste ...

also ich schreibe gerade an einer verketteten liste, und jetzt habe ich da irgendwie ein problem mit dem löschen der liste..

ich hab eigentlich nur eine frage..
die ganze liste ist eine klasse für sich, die intern alles verwaltet.
also wenn ich die klasse instanziere habe ich ein objekt, dass halt einfach die liste verwalten kann.. jetzt frage ich mich..
reicht es wenn ich das objekt lösche, sodass der gesamte speicher freigegeben wird, oder muss ich in einer schleife alle elemente einzeln löschen, und dann zusätzlich das objekt freigeben?
Am Anfang der Weisheit steht die eigene Erkenntnis, dass man selbst nichts weiß! - Sokrates

rewb0rn

Supermoderator

Beiträge: 2 773

Wohnort: Berlin

Beruf: Indie Game Dev

  • Private Nachricht senden

2

09.03.2007, 11:52

ja du musst alle elemente einzeln freigeben, also etwa so:

C-/C++-Quelltext

1
2
3
4
5
Liste::~Liste()
{
    für alle elemente:
        lösche element;
}


Das Objekt selbst musst du nicht gesondert freigeben (es besteht ja nur aus seinen Unterobjekten)

achte aber darauf, dass du nur diejenigen teile der klasse freigibst, die innerhalb der klasse erzeugt werden.

sähe also deine insert methode so aus:

C-/C++-Quelltext

1
2
3
4
Liste::insert(Objekt* Obj)
{
    _liste.insert(Obj);
}


wäre es falsch, alle Objekte mit delete im Destruktor der Klasse freizugeben, weil sie außerhalb der Klasse erzeugt wurden und damit konsequenterweise auch außerhalb der Klasse wieder freigegeben werden sollten. Ich hoffe das war einigermaßen verständlich.

Übrigens für den Fall dass du die Liste nicht nur zu Übungszwecken erstellst, die stl hat eine wunderbare liste, zu finden unter std::list

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

3

09.03.2007, 12:59

Wenn du ein Klassentemplate machst musst du darauf achten das, wenn der Templateparameter ein Zeiger auf ein Objekttyp ist, auch der Inhalt freigegeben wird. Normal überlässt man die Freigabe des Speichers dem Benutzer, du kannst aber auch eine Funktion schreiben die durch deine Items iteriert und die entsprechenden Objekte freigibt.

Nur so als Tip!

grüße
@D13_Dreinig

helium

Treue Seele

Beiträge: 180

Wohnort: NRW, Burscheid (nahe Köln)

  • Private Nachricht senden

4

09.03.2007, 14:14

Re: verkettete liste ...

Zitat von »"$nooc"«

also ich schreibe gerade an einer verketteten liste, und jetzt habe ich da irgendwie ein problem mit dem löschen der liste..

ich hab eigentlich nur eine frage..
die ganze liste ist eine klasse für sich, die intern alles verwaltet.
also wenn ich die klasse instanziere habe ich ein objekt, dass halt einfach die liste verwalten kann.. jetzt frage ich mich..
reicht es wenn ich das objekt lösche, sodass der gesamte speicher freigegeben wird, oder muss ich in einer schleife alle elemente einzeln löschen, und dann zusätzlich das objekt freigeben?

Du musst das freigeben, was du angelegt hast. pro new ein delete
Why is 6 afraid of 7?
Because 7 8 9

$nooc

Alter Hase

  • »$nooc« ist der Autor dieses Themas

Beiträge: 873

Wohnort: Österreich / Kärnten

Beruf: Schüler

  • Private Nachricht senden

5

09.03.2007, 15:14

ja aber wie soll ich die freigeben?
ich hab ja kein array oder so, sondern nur strukturen die aufeinander zeigen. also im sinne einer verketteten liste! wie soll ich die da jetzt noch einzeln löschen?
Am Anfang der Weisheit steht die eigene Erkenntnis, dass man selbst nichts weiß! - Sokrates

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

6

09.03.2007, 15:35

die liste durchlaufen und jedes element löschen!?

C-/C++-Quelltext

1
2
3
4
5
6
7
ListItem* item = first;

while(ListItem* dummy = item)
{
    item = item->next;
    delete dummy;
}


z.b. so in der art...

$nooc

Alter Hase

  • »$nooc« ist der Autor dieses Themas

Beiträge: 873

Wohnort: Österreich / Kärnten

Beruf: Schüler

  • Private Nachricht senden

7

09.03.2007, 18:02

so hab ichs sogar schon versucht :D
aber irgendwie waren die elemente noch immer da, als ich sie anzeigen lies..
Am Anfang der Weisheit steht die eigene Erkenntnis, dass man selbst nichts weiß! - Sokrates

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

8

09.03.2007, 18:45

Der Speicher wird freigegeben, aber nicht gelöscht. Das macht insofern Sinn als das große Speicherfragmente sehr viel Zeit beanspruchen würden für eine Freigabe. Also wird der entsprechende Teil einfach wieder zur weiteren Benutzung bereitgestellt behält aber seinen Inhalt.

grüße
@D13_Dreinig

riCo

Treue Seele

Beiträge: 165

Beruf: Student

  • Private Nachricht senden

9

10.03.2007, 11:07

Ein delete verbinde ich im Normalfall immer mit einer Nullsetzung(delete x; x = NULL). Das kann dir viel Ärger beim Debuggn sparen.

Übrigens: Wenn du ein Objekt innerhalb der verketteten Liste löschst, vergiss nicht den next-Pointer richtig zu platzieren.
Wir leben alle unter dem Sternenhimmel, aber wir haben nicht alle den gleichen Horizont.

$nooc

Alter Hase

  • »$nooc« ist der Autor dieses Themas

Beiträge: 873

Wohnort: Österreich / Kärnten

Beruf: Schüler

  • Private Nachricht senden

10

10.03.2007, 12:19

das ist es ja.. ich lösche die struktur nicht nur.. ich setze sie auch auf NULL ... aber wenn ich dann eine andere funktion aufrufe die mir alle elemente wiedergeben soll, dann startet diese bei der ersten struktur und geht mir alle durch und gibt sie aus.. naja ich denke ich poste etwas code.. warscheinlich hab ich ganz einfach was falsch verstanden ^^

ich muss dazu sagen dass ich die verkettete liste ohne hilfe bis jetzt geschrieben habe.. also ohne beispiele ausn internet oder so.. also werden da vllt. einige dinge drinnen sein, die man warscheinlich anders viel leichter lösen könnte.. ich wollte es einfach mal auf "just do it yourself" versuchen.. :)

das ist mal das was ich in der main aufrufe ..
der constructor von ChainedList macht eigentlich nur eines.. er setzt die pointervariable die später auf das erste objekt in der liste zeigt auf NULL
m_pPtrToFirstElement = NULL;

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
// M a i n

int main()
{
    ChainedList *pList;
    pList = new ChainedList;

    pList->Add(0);
    pList->Add(1);
    pList->Add(2);
    pList->Add(3);

    pList->ShowList();      // Zeigt alles an ..

    pList->DeleteList();
    pList->ShowList();      // Zeigt ebenfalls alles an ..


    getchar();

    PTR_DELETE(pList);

    getchar();

    return 0;
} // main()


die funktion Add(); funktioniert eigentlich.. später will ich sie umschreiben, sodass ich die elemente auch in der mitte der liste bzw. irgendwo in der liste einfügen kann.. vorerst reicht es mir wenn ich die elemente in einer reihe hinzufügen kann..

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
unsigned long ChainedList::Add(int Value)
{
        // If there is no element at all:

    if (m_pPtrToFirstElement == NULL)
    {
        Element *pAddElement;
        pAddElement = new Element;
        
        pAddElement->m_ListNr           = 0;
        pAddElement->m_Value            = Value;
        pAddElement->m_pPrevElement = NULL;
        pAddElement->m_pNextElement = NULL;

        m_pPtrToFirstElement = pAddElement;
        m_pPtrToLastElement = m_pPtrToFirstElement;

        return 0;
    }

    Element *pCurElement;
    pCurElement = new Element;

    Element *pAddElement;
    pAddElement = new Element;

    pCurElement = m_pPtrToFirstElement;

    while(pCurElement != NULL)
    {
        if((pCurElement->m_pNextElement) == NULL)
        {
            pAddElement->m_ListNr = pCurElement->m_ListNr + 1;
            pAddElement->m_Value = Value;

                // Chain the elements ..

            pAddElement->m_pNextElement = NULL;
            pAddElement->m_pPrevElement = pCurElement;

            pCurElement->m_pNextElement = pAddElement;
            m_pPtrToLastElement = pAddElement;
        
            return 0;
        } // while(pCurElement != NULL)


        pCurElement = pCurElement->m_pNextElement;
    }

    return 0;
} // Add()


ShowList(); nimmt einfach nur m_pPtrToFirstElement(); und gibt alle elemente mittels einer while schleife aus..

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
unsigned long ChainedList::ShowList(void)
{
    Element *pCurElement;
    pCurElement = new Element;

    if((pCurElement = m_pPtrToFirstElement) == NULL)
    { return 0; }

    while(pCurElement != NULL)
    {
        cout << "Element Nr. " << pCurElement->m_ListNr << endl;
        cout << "Wert: "<< pCurElement->m_Value << endl << endl;

        pCurElement = pCurElement->m_pNextElement;
    } // while(pCurElement != NULL)


    PTR_DELETE(pCurElement);

    return 0;
} // ShowList()



tja und zu guter letzt kommt eben die eine funktion die nicht funktioniert ^^ ich glaube ich hab einfach nen komplett falschen denkansatz bei der funktion .. nur zur info: den pointer m_pPtrToFirstElement lasse ich am leben, damit ich eben danach nochmal die funktion ShowElements(); aufrufen kann, um zu testen ob alles funktioniert hat.. aber naja.. tut es eben nicht :D

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
unsigned long ChainedList::DeleteList(void)
{
    Element *pDeleteMe;
    pDeleteMe = new Element;
    pDeleteMe = m_pPtrToFirstElement;

    Element *pDummy;
    pDummy = new Element;
    
    while(pDeleteMe != NULL)
    { 
        pDummy = pDeleteMe->m_pNextElement;
        if(pDummy != NULL)
        {
            pDummy->m_pPrevElement = NULL;
            PTR_DELETE(pDeleteMe);

            pDeleteMe = new Element;
            pDeleteMe = pDummy;
        }
        else
        {
            PTR_DELETE(pDeleteMe);
        }
    } // while(pDeleteMe != NULL)


    PTR_DELETE(pDummy);

    return 0;
} // DeleteList()


edit:
hier noch die template funktion PTR_DELETE();

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
template<class T>
void PTR_DELETE(T &pPtr)
{
    if(pPtr != NULL)
    {
        pPtr = NULL;
        delete pPtr;    
    }
} // PTR_DELETE()
Am Anfang der Weisheit steht die eigene Erkenntnis, dass man selbst nichts weiß! - Sokrates

Werbeanzeige