Christian: (C++) Was muss alles per "delete" gelöscht werden?

Hallo,

ich schreiben gerade an einem Programm in C++, und nach mehrmaligem Ausführen und Erzeugen neuer Instanzen (innerhalb des Programms), kam irgendwann die Meldung: "Wenig virtueller Speicher". Ui ui ui dachte ich.

Hatte natürlich meine Objekte nicht deleted.
Nun die Frage, was muss ich denn alles deleten?

//// 1. ////
Auch Objekte, die lokal innerhalb einer Methode mit new erzeugt wurden?
Also
void Test()
{
    MyClass *mc = new MyClass();

// [...]
    delete mc; // ????
}

Oder werden diese automatisch gelöscht?

//// 2. ////
Oder Objekte, die Eigenschaften einer Klasse sind?

class MyClass
{
MyClass2 *mc;
};

void MyClass::Methode()
{
   mc->myMethod();
}
MyClass::~MyClass()
{
  delete mc; // ???????
}

//// 3. ////
Objekte die NICHT als Referenz angelegt wurden?
void Method()
{
  MyClass mc;
  mc.Method();

// delete mc; ?????
}

//// 4. ////
Objekte, die Eigenschaften einer Klasse sind, aber nicht als Referenz angelegt sind.
class MyClass
{
   MyClass2 mc2;
};

Bitte um Hilfe!

Danke,
Christian

  1. Hatte natürlich meine Objekte nicht deleted.
    Nun die Frage, was muss ich denn alles deleten?

    Alles, was explizit nicht auf dem Stack, also mit new angelegt wurde.

    //// 1. ////
    Auch Objekte, die lokal innerhalb einer Methode mit new erzeugt wurden?

    Klar. Mit new legst du ein Objekt auf dem Heap an. Du musst es von dort
    auch selber wieder löschen.

    void Test()
    {
        MyClass *mc = new MyClass();

    // [...]
        delete mc; // ????
    }

    Ja.

    //// 2. ////
    Oder Objekte, die Eigenschaften einer Klasse sind?

    Wenn du sie mit new anlegst -- ja. Wenn du sie nicht per new
    anlegst -- nein. Grob gesagt, alles, was ein Pointer ist, muss auch wieder
    gelöscht werden.

    class MyClass
    {
    MyClass2 *mc;
    };

    void MyClass::Methode()
    {
       mc->myMethod();
    }
    MyClass::~MyClass()
    {
      delete mc; // ???????
    }

    Ja, da Pointer.

    //// 3. ////
    Objekte die NICHT als Referenz angelegt wurden?
    void Method()
    {
      MyClass mc;
      mc.Method();

    // delete mc; ?????
    }

    Nein, kein Pointer, passiert automatisch.

    Objekte, die Eigenschaften einer Klasse sind, aber nicht als Referenz
    angelegt sind.
    class MyClass
    {
       MyClass2 mc2;
    };

    Nein, kein Pointer, passiert automatisch.

    1. Hi,

      Wenn du sie mit new anlegst -- ja. Wenn du sie nicht per new
      anlegst -- nein. Grob gesagt, alles, was ein Pointer ist, muss auch wieder
      gelöscht werden.

      Ok! Mich wundert es dann aber nur, dass ich schon öfters programme gesehen habe, auch Beispiel/Lehrprogramme, wo nicht alles was mit new angelegt wurde wieder gelöscht wird.
      Daher hat mich das eben gewundert, und ich habe hier gepostet.

      Noch eine Frage: Wenn ich mein Programm komplett beende, der Prozess also terminiert (sagt man doch so!?), kann der Speicher vom Betriebssystem nicht wieder automatisch frei gegeben werden?
      (scheinbar nicht)

      Gruß
      Christian

      1. Hallo,

        Ok! Mich wundert es dann aber nur, dass ich schon öfters programme gesehen habe, auch Beispiel/Lehrprogramme, wo nicht alles was mit new angelegt wurde wieder gelöscht wird.

        Das sind dann schlechte Beispielprogramme ;-) und der Ersteller war etwas faul.

        Noch eine Frage: Wenn ich mein Programm komplett beende, der Prozess also terminiert (sagt man doch so!?), kann der Speicher vom Betriebssystem nicht wieder automatisch frei gegeben werden?
        (scheinbar nicht)

        Normalerweise sollte das Betriebssystem das tuen. Allerdings muß dazu das Programm auch vollständig beendet sein. Es reicht nicht aus, wenn nur die Funktion oder der Thread, in dem Du das Objekt erzeugt hast, beendet wird. Dazu muß das Betriebssystem aber sowas wie Speicherschutz beherrschen. Bei Windows98 wäre ich mir da also nicht so sicher.

        1. Dazu muß das Betriebssystem aber sowas wie Speicherschutz beherrschen.

          Naja, nicht wirklich; es muss nur die Ressourcen zuordnen können. DOS konnte das z. B. nicht, da hat das die libc dann übernommen. In der glibc gibt es heute noch die entsprechenden Routinen (libc-freeres).