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

drakon

Supermoderator

  • »drakon« ist der Autor dieses Themas

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

1

01.01.2007, 17:48

Frage zu Listing 9.4 Verkette Listen

Hallo

Ich habe ein kleines Problem mit dem Listing 9.4.
Es ist mehr ein Verständnissproblem.
Dort wird ja eine Liste von Zeigern, welche auf Instanzen einer Klasse zeigen erstellt.
Nun wird dort mit new neue Instanzen erstellt und dann die Adresse in die Liste zugefügt.
Am Schluss wird ja mit delete die Instanz ja wieder freigegen und der Zeiger auf die Instanz auf NULL gestellt.
Nun verstehe ich aber nicht, wie ich dann dennoch auf die Instanzen zugreifen kann, respektive sie mir anzeigen lassen kann.
EDIT: Rein nach meiner Überlegung habe ich gedacht, dass zwar die Anzahl in der Liste noch bestehen bleibt, aber einfach die Zeiger alle leer sind.

Zum Verständniss für mich:
Die Liste beinhaltet ja nur Zeiger auf Instanzen der erstellten Klassen, welche irgendwo sind. Der Iterator ist ein Zeiger auf eben diese Zeiger, welche auf die Instanzen zeigen. Wenn ich nun ja mittels des Iterators die Instanz freigebe, dann besteht sie ja immernoch, aber sie ist nicht mehr "geschützt".Und der Zeiger auf die Instanz wird ja mit NULL eigentlich "vernichtet". Kommt das irgendwie hin?-Oder kann mir das jemand genau erklären? (Für meinen Geschmack wird im Buch zu wenig auf die Theorie eingegangen.)

lg drakon

2

01.01.2007, 18:34

In dem Beispiel werden die Instanzen ja ganz zum Schluss freigegeben und so wie ich das sehe wird da auch nicht mehr darauf zugegriffen.

Zum Verständnis:

Die Liste beinhaltet ja Zeiger, die auf einen Speicherbereich zeigen, der Instanzen der Klasse beinhalten. Nachdem du den mit delete gelöscht hast zeigen die Zeiger auf diesen Speicherbereich aber der Inhalt ist unbekannt. Darum setzt du ihn auf NULL und in dem Speicherbereich sind nur noch Nullen. Darum dürftest du eigentlich nicht mehr eine Instanz der Klasse dort vorfinden.

EDIT: Die Zeiger bleiben in der Liste enthalten, aber sie zeigen halt nur auf einen Speicherbereich der mit NULL gefüllt ist
Ich gebe bei der Arbeit immer 100%

6% Montags
30% Dienstags
35% Mittwochs
25% Donnerstag
4% Freitag

drakon

Supermoderator

  • »drakon« ist der Autor dieses Themas

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

3

01.01.2007, 18:48

Ja mit .clear wird es wieder ganz freigegeben, aber im Buch steht in der Erklärung, dass die Einträge in der Liste enthalten bleiben.
Ich habe es ausprobiert, solange man nicht .clear macht, kann man ganz normal auf die Objekte zugreifen. Das ist es eben, was ich nicht verstehe.
Ich habe auch gedacht, dass einfach die Zeiger freigegeben werden und auf NULL zeigen,was sie aber nicht machen!

4

01.01.2007, 18:55

Nach dem Freigeben ist es das gleiche wie dieser Code:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>

class C
{
public:
     
    int i;
};

int main ()
{
     C *p = NULL;
    
     std::wcout << p->i << std::endl;

     return 0;
}


Dieser Code lässt sich auch kompilieren erzeugt aber einen Laufzeitfehler. Weil der zeiger eben auf einen leeren Speicherbereich zeigt.
Ich gebe bei der Arbeit immer 100%

6% Montags
30% Dienstags
35% Mittwochs
25% Donnerstag
4% Freitag

drakon

Supermoderator

  • »drakon« ist der Autor dieses Themas

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

5

01.01.2007, 18:58

Nein, ich meine nicht, das er sich nur erzeugen lässt, er bringt sogar das vermeindliche richtige Ergebniss.
Ich habe jetzt mal den Zeiger anzeigen lassen, der steht tatsächlich auf NULL, aber in der nächsten Zeile greift er richtig darauf zu, obwohl doch alles auf NULL steht.

drakon

Supermoderator

  • »drakon« ist der Autor dieses Themas

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

6

01.01.2007, 19:00

Effektiv sieht man es an diesem Code:

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
#include <iostream>
#include <list>


using namespace std;

class CRaumschiff
{
public:
    CRaumschiff ()
    {
        cout << "Konstruktor" << endl;
    }
    ~CRaumschiff ()
    {
        cout << "Destruktor" << endl;
    }

    void starten ()
    {
        cout << "Starten" << endl;
    }
private:

};

int main ()
{

    list<CRaumschiff*> lSchiffeSpieler;
    list<CRaumschiff*> lSchiffeGegner;
    list<CRaumschiff*>::iterator i;
    int Auswahl = 0;
    CRaumschiff* Temp = NULL;

    
    
    do
    {
    system ("cls");
    cout << "Was wollen Sie tun?" << endl;
    cout << "1. Schiff fuer Spieler." << endl;
    cout << "2. Schiff fuer Gegner. " << endl;
    cout << "3. Liste ausgeben. " << endl;
    cout << "4. Beenden." << endl;

    cin >> Auswahl;

    switch (Auswahl)
    {
    case 1:
        {
            Temp = new CRaumschiff;
            lSchiffeSpieler.push_back (Temp);
        }break;

    case 2:
        {
            Temp = new CRaumschiff;
            lSchiffeGegner.push_back (Temp);
        }break;
    case 3:
        {
            cout << "Spieler: " << endl;
            for (i = lSchiffeSpieler.begin(); i != lSchiffeSpieler.end(); i++)
                (*i)->starten ();
            cout << "Gegner: " << endl;
            for ( i = lSchiffeGegner.begin(); i != lSchiffeGegner.end(); i++)
                (*i)->starten ();
        }break;
    }

    }while(Auswahl != 4);


    for(i = lSchiffeSpieler.begin (); i!=lSchiffeSpieler.end (); i++)
    {
        delete *i;
        *i= NULL;
    }

    for(i = lSchiffeGegner.begin (); i!=lSchiffeGegner.end (); i++)
    {
        delete *i;
        *i= NULL;
    }

    for (i = lSchiffeSpieler.begin(); i != lSchiffeSpieler.end(); i++)
        cout << *i << endl;

    

    cout << "Spieler: " << endl;
    for (i = lSchiffeSpieler.begin(); i != lSchiffeSpieler.end(); i++)
        (*i)->starten ();
    cout << "Gegner: " << endl;
    for ( i = lSchiffeGegner.begin(); i != lSchiffeGegner.end(); i++)
        (*(*i)).starten ();

    lSchiffeSpieler.clear ();
    lSchiffeGegner.clear ();


return 0;
}


Ist jetzt mehr, als nötig wäre, aber ich habe es mit dem Beispiel probiert.
Und hier sieht man bei der Ausgabe dann die Nullen.

7

01.01.2007, 19:00

zeig mal bitte deinen Code.

EDIT:
:lol:

zu spät.
Ich gebe bei der Arbeit immer 100%

6% Montags
30% Dienstags
35% Mittwochs
25% Donnerstag
4% Freitag

8

01.01.2007, 19:09

Hab einen Test gemacht:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>

class C
{
public:
    int i () { std::cout << "i" << std::endl; return 1;}

};

int main ()
{

    C *p = NULL;

    std::cout << p->i ();

    std::cin.get ();

    return 0;
}


Dieser Code Funktioniert auch ohne Abstürze weil so eine Klasse nicht auf irgendwelche variablen zurückgreift, die konstruiert werden müssen. So ist es auch bei deinem Beispiel.
Ich gebe bei der Arbeit immer 100%

6% Montags
30% Dienstags
35% Mittwochs
25% Donnerstag
4% Freitag

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

9

01.01.2007, 19:10

Das Ergebniss ist Implementierungsabhängig. Genau der gleiche Effekt wie hier:

C-/C++-Quelltext

1
( ( CRaumschiff *)NULL )->starten();


Kann klappen, kann aber auch ganz böse in die Hose gehen! Sinn macht es aber in keinen Fall.
@D13_Dreinig

drakon

Supermoderator

  • »drakon« ist der Autor dieses Themas

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

10

01.01.2007, 19:17

Ich habe es jetzt mal noch mit einer Membervariabel probiert, und jetzt stürtzt bei mir das Programm auch ab.
Ok, wenn ich es jetzt richtig verstanden habe geht es solange ich keine Membervariabeln habe, weil die ja keinen Speicher reservieren müssen.

Werbeanzeige