Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Generelle Frag zu destruktor und Memoryleaks

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
08.05.2010, 15:36 Uhr
Moritz1243



Hallo zusammen,

ich habe für mein Programm die eine Klasse Vector3D erstellt. Wenn ich diese jetzt in einer funktionen wie folgt nutze:


C++:


void funktion()
{
Vector3D<double> tmp_vector;

....

tmp_vector.~Vector3D();
}



muss ich ihr den destruktor aufrufen? Ebenso wenn ich ein struct habe mit mehreren strings muss die strings löschen oder clearen bevor ich das struct lösche?

Dieser Post wurde am 08.05.2010 um 15:36 Uhr von Moritz1243 editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
08.05.2010, 15:42 Uhr
0xdeadbeef
Gott
(Operator)


Um Himmels Willen, nein! Den Destruktor ruft man direkt nur auf, wenn man mit placement new arbeitet.

Also, das funktioniert so: Ein Objekt hat einen Geltungsbereich, an dessen Anfang es gebaut und an dessen Ende es zerstört wird. Beim Bauem wird der Konstruktor aufgerufen, beim Zerstören der Destruktor - Beispiel:

C++:
#include <iostream>

struct A {
  A() { std::cout << "Konstruktor A" << std::endl; }
  ~A() { std::cout << "Destruktor A" << std::endl; }
};

int main() {
  std::cout << "trace 1" << std::endl;

  {
    std::cout << "trace 2" << std::endl;
    A a;
    std::cout << "trace 3" << std::endl;
  }

  std::cout << "trace 4" << std::endl;
}

// Ausgabe:
//
// trace 1
// trace 2
// Konstruktor A
// trace 3
// Destruktor A
// trace 4


Wenn du ein Objekt für längere Zeit brauchst, musst du es auf den Heap legen. Das sieht dann so aus:

C++:
int main() {
  A *a;
  A *arr;

  {
    a   = new A;     // Ein Konstruktor wird ausgeführt
    arr = new A[10]; // 10 Konstruktoren werden ausgeführt
  } // Hier wird diesmal nichts zerstört

  // Das muss von Hand so passieren:
  delete   a;   // Ein Destruktor
  delete[] arr; // 10 Destruktoren
}


Der Geltungsbereich eines Memberobjektes ist dabei der selbe des Objektes, das ihn enthält. Also:

C++:
#include <iostream>

struct A {
  A() { std::cout << "Konstruktor A" << std::endl; }
  ~A() { std::cout << "Destruktor A" << std::endl; }
};

struct B {
  B() { std::cout << "Konstruktor B" << std::endl; }
  ~B() { std::cout << "Destruktor B" << std::endl; }

  A a;
};

int main() {
  std::cout << "trace 1" << std::endl;
  {
    std::cout << "trace 2" << std::endl;
    B b;
    std::cout << "trace 3" << std::endl;
  }
  std::cout << "trace 4" << std::endl;
}

// Ausgabe
//
// trace 1
// trace 2
// Konstruktor A
// Konstruktor B
// trace 3
// Destruktor B
// Destruktor A
// trace 4


Wenn du innerhalb eines Objektes einen Zeiger auf ein Heap-Objekt verwaltest, solltest du dieses im Destruktor löschen, etwa

C++:
struct B {
  B() : p(new A()) { }
  ~B() { delete p; }

  A *p;
};


--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 08.05.2010 um 15:47 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
08.05.2010, 15:52 Uhr
Moritz1243



Muss ich für jedes struct zwangläufig einen destructor anlegen oder für jede klasse?
Dieser Post wurde am 08.05.2010 um 15:57 Uhr von Moritz1243 editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
08.05.2010, 16:00 Uhr
0xdeadbeef
Gott
(Operator)


Wenn du keinen angibst, erstellt der Compiler (falls nötig) einen für dich, der halt schlicht die Member aufräumt. In der Praxis braucht man Destruktoren hauptsächlich, um Ressourcen wieder freizugeben, bei denen das nicht automatisch geschieht - Heap-Objekte, Sockets, derartige Dinge.

Wobei es für viele dieser Fälle in der Standardbibliothek oder Boost bereits RAII-Klassen gibt, die dir die Arbeit abnehmen. Etwa kann mein letztes Beispiel von oben auch so geschrieben werden:

C++:
#include <memory>

struct B {
  B() : p(new A()) { }

  std::auto_ptr<A> p;
}


...der std::auto_ptr wird zerstört, wenn das B-Objekt zerstört wird, und sein Destruktor räumt das Objekt auf dem Heap auf. Es ist auf die Art auch deutlich besserer Stil, aber wir besprachen ja gerade die Mechanismen dahinter.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
08.05.2010, 16:05 Uhr
Moritz1243



Mmh okey, ich habe noch meine frage gestellt da ich meinenm Programm ein Memory leak habe und nicht weiß wo (logisch sonst hätte ich keines mehr), es ist ein 3D spiel mit der opengl lib. Für das Programm benutze ich die vectoren um die ganzen information zu speichern. die vectoren enthalten structs die wiederrum vectoren enthalten. Ebenso enthalten manche klassen strings. Muss ich diesen sache bestimmt sachen beachten in bezug auf memory leaks?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
08.05.2010, 16:12 Uhr
0xdeadbeef
Gott
(Operator)


Naja, ein Speicherleck heißt, dass du irgendwo Heap-Speicher angefordert hast, ihn aber nicht wieder freigibst. Irgendwo hast du zu einem new kein passendes delete oder zu einem new[] kein passendes delete[].

Lass mal valgrind drüberlaufen, vielleicht findet der es ja.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
08.05.2010, 16:15 Uhr
Moritz1243



Valgrinds? ich habe code blocks wie mache ich das?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
08.05.2010, 16:20 Uhr
0xdeadbeef
Gott
(Operator)


Valgrind ist ein Memory-Debugger für Linux und MacOS X. Naja, sein meistbenutztes Frontend ist ein Memory-Debugger. Zum Finden von Speicherlecks unersetzlich.

Wenn du unter Windows arbeitest, wirst du dich aber nach einem Ersatz umsehen müssen.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: