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

koschka

Community-Fossil

  • »koschka« ist der Autor dieses Themas

Beiträge: 2 862

Wohnort: Dresden

Beruf: Student

  • Private Nachricht senden

1

06.12.2003, 11:16

Mal ne dumme Frage zu Strukturen und Klassen

Hi, ich in allen meinen C/C++ Bücher mal nachgekuckt, aber nirgends hab ich eine eindeutige Antwort zu folgendem Problem gefunden:

Ich hab eine Klasse und eine Struktur, die Struktur besteht aus "Zeigervariblen" z.B.

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    struct stest  {
        char* Name;
        UINT Parameter;
    };

    class ctest   {
    private:
        stest Stuktur;
        UINT andererparameter;
    public:
        //Konstructor
        ctest(UINT Num);
        // Destructor
        ~ctest();
    };


muss ich jetzt ctest::Name auch per Speicherbelegung zuweisen --- sicher lich ja oder?

also so:

Quellcode

1
2
3
4
5
6
7
8
    ctest::ctest(UINT Num)  {
        this->Stuktur.Name = new char [128 + 1];
        this->Stuktur = new stest [Num];
    }
    ctest::~ctest()  {
        delete[] this->Stuktur.Name;
        delete[] this->Stuktur;
    }

Till

Alter Hase

Beiträge: 378

Wohnort: Lincoln College, Oxford

Beruf: Student

  • Private Nachricht senden

2

06.12.2003, 12:10

ich nehme schon an...

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

3

06.12.2003, 12:13

Was sollen diese Zeilen hier:

Quellcode

1
2
    this->Stuktur.Name = new char [128 + 1]; 
      this->Stuktur = new stest [Num]; 


Die zweite Zeile ist doch überflüssig!
Sie hebt ja sogar die Wirkung der ersten Zeile wieder auf.
Außerdem müsste es eigentlich einen Compiler-Fehler geben...

koschka

Community-Fossil

  • »koschka« ist der Autor dieses Themas

Beiträge: 2 862

Wohnort: Dresden

Beruf: Student

  • Private Nachricht senden

4

06.12.2003, 12:18

Ahso! also müsset das delete[] auch noch weg, oder?

Quellcode

1
delete[] this->Stuktur.Name; 


Aber irgendwie versteh ich das nicht! Weil Sturktur doch ein Zeiger ist!

koschka

Community-Fossil

  • »koschka« ist der Autor dieses Themas

Beiträge: 2 862

Wohnort: Dresden

Beruf: Student

  • Private Nachricht senden

5

06.12.2003, 12:22

Nun mal ein kongretes Beispiel:
(vielleicht kapier ich das besser, hier liegen keine Fehlermeldungen vor und es funktioniert auch!

Quellcode

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
struct sEntry  {
    char* to;
    char* from;
};


class CopyList  {
private:
    UINT Entries;
    UINT MaxEntries;

    sEntry *CopyEntries;
public:
    CopyList();
    CopyList(UINT MaxEntries);
    ~CopyList();

    void Alloc(UINT MaxEntries);
    void AddEntry(char* from, char* to);
    isResult Copy(UINT Number);

    void GetCopyParameters();

    inline UINT GetEntries()        { return this->Entries; }
    inline UINT GetMaxEntries()     { return this->MaxEntries; }
};


Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
CopyList::CopyList(UINT MaxEntries)  {
    this->Entries = 0;
    this->MaxEntries = MaxEntries; 

    this->CopyEntries = new sEntry [MaxEntries + 1];

    IS_INFO_MSG("[<i>Klassen</i>] CCopyList erstellt [<i>Initialisierung komplett</i>]");
}
CopyList::~CopyList()  {
    IS_INFO_MSG("[<i>Klassen</i>] CCopyList reinitialisiert");

    for(UINT uiEntry = 0; uiEntry < this->Entries; uiEntry++)  {
        IS_SAFE_DELETE_ARRAY(this->CopyEntries[uiEntry].from);
        IS_SAFE_DELETE_ARRAY(this->CopyEntries[uiEntry].to);
    }
    
    IS_SAFE_DELETE_ARRAY(this->CopyEntries);    
}


Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void CopyList::AddEntry(char* from, char* to)  {
    if(this->MaxEntries <= 0)  { return; }
    
    if(from == NULL || to == NULL)  { return; }
    
    if(this->Entries >= this->MaxEntries)  {
        return;
    }

    this->CopyEntries[this->Entries].from = new char [strlen(from) + 1];
    strcpy(this->CopyEntries[this->Entries].from, from);

    this->CopyEntries[this->Entries].to = new char [strlen(to) + 1];
    strcpy(this->CopyEntries[this->Entries].to, to);

    this->Entries++;
}

Till

Alter Hase

Beiträge: 378

Wohnort: Lincoln College, Oxford

Beruf: Student

  • Private Nachricht senden

6

06.12.2003, 14:11

Das ist doch was ganz was anderes!

Hier hast du in der Klasse 'CopyList' einen sEntry-Zeiger, dieser wird dynamisch allokiert und die Zeiger in den Arrayelementen werden auch noch dynamisch reserviert!
Natürlich müssen die ja dann freigegeben werden und die Struktur am Ende auch noch.

koschka

Community-Fossil

  • »koschka« ist der Autor dieses Themas

Beiträge: 2 862

Wohnort: Dresden

Beruf: Student

  • Private Nachricht senden

7

06.12.2003, 17:46

Oh, ich sehe gerade, ich hab oben den Zeiger auf die Variable vergessen :angel: , ne also das Beispiel unten Stimmt, es entsteht so KEIN Speicherleck, ja!

8

08.12.2003, 01:57

Re: Mal ne dumme Frage zu Strukturen und Klassen

Zitat von »"koschka"«

Hi, ich in allen meinen C/C++ Bücher mal nachgekuckt, aber nirgends hab ich eine eindeutige Antwort zu folgendem Problem gefunden:

Ich hab eine Klasse und eine Struktur, die Struktur besteht aus "Zeigervariblen" z.B.

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    struct stest  {
        char* Name;
        UINT Parameter;
    };

    class ctest   {
    private:
        stest Stuktur;
        UINT andererparameter;
    public:
        //Konstructor
        ctest(UINT Num);
        // Destructor
        ~ctest();
    };


muss ich jetzt ctest::Name auch per Speicherbelegung zuweisen --- sicher lich ja oder?

also so:

Quellcode

1
2
3
4
5
6
7
8
    ctest::ctest(UINT Num)  {
        this->Stuktur.Name = new char [128 + 1];
        this->Stuktur = new stest [Num];
    }
    ctest::~ctest()  {
        delete[] this->Stuktur.Name;
        delete[] this->Stuktur;
    }
Doch es entsteht eines. Wenn du ein Array, vom Typ "stest", Allokierst, must du auch bei jedem Array-Element "stest::Name" freigeben. Ich empfehle dir einenen Konstruktor und einen Destruktor fuer deine Struktur "stest" zu schreiben, die Speicher fuer die Variabel "stest::Name" reservieren und wieder freigeben.

PS: Strukturen sind KEINE Zeiger sondern Selbstdefinierte Typen.
Wichtig! Ich übernehme keinerlei Verantwortung für eventl. Datenverlust oder Schäden am Rechner ;D

koschka

Community-Fossil

  • »koschka« ist der Autor dieses Themas

Beiträge: 2 862

Wohnort: Dresden

Beruf: Student

  • Private Nachricht senden

9

08.12.2003, 18:05

Ja, is ok, ich hab mich bei dem Beispiel vertan! bei struktur muss ein Zeiger hin!

also:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
   struct stest  { 
      char* Name; 
      UINT Parameter; 
   }; 

   class ctest   { 
   private: 
      stest* Stuktur;  // hier ist der vesgessene Zeiger *schäm* :) 
      UINT andererparameter; 
   public: 
      //Konstructor 
      ctest(UINT Num); 
      // Destructor 
      ~ctest(); 
   };


und dann stimmt auch
das: wie ich das jetzt mitgekriegt habe:

Quellcode

1
2
3
4
5
6
7
8
ctest::ctest(UINT Num)  { 
      this->Stuktur = new stest [Num]; 
      this->Stuktur.Name = new char [128 + 1]; 
   } 
   ctest::~ctest()  { 
      delete[] this->Stuktur.Name; 
      delete[] this->Stuktur; 
   }


Eigentlich ist dieser Programmtext sowieso totaler Schwachfug, aber naja, es ging nur ums Prinzip

Werbeanzeige