Announcement

Collapse
No announcement yet.

Anfängerfrage zum Instanzieren von Objekt

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Anfängerfrage zum Instanzieren von Objekt

    Hallo zusammen,

    ich habe mir jetzt mehrere Bücher zum Thema C++ reingezogen - allerdings wurde mir die folgende Frage nie beantwortet:

    Wenn ich eine Klasse, z. B. mit dem Namen "Auto" geschrieben habe und Objekte davon erzeugen möchte.
    Instanziere ich die dann mit

    Auto meinAuto;

    oder mit Zeiger

    Auto *meinAuto = new Auto;

    Wenn ich das richtig sehe, wird die erste Variante auf dem Stack erzeugt - die zweite (Zeiger-Variante) auf dem Heap.

    Meine Frage:
    Wann erzeuge ich ein Objekt auf dem Stack (Möglichkeit 1) und wann mit der Zeiger-Variate auf dem Heap - von was hängt das ab?
    Manche Datentypen, z. B. dynamische Listen lassen sich ja nur über Zeiger (und somit auf dem Heap) realisieren.
    Aber z. B. für eigene Klassen weiss ich nicht, wann ich mit welcher Variante erzeuge?

    cu
    Chris

  • #2
    Da der Stack begrenzt ist kannst Du Ärger bekommen, wenn Du dort zu viel allozierst. Deswegen würde ich Dir die zweite Variante ans Herz legen

    [highlight=c++]
    Auto *meinAuto = new Auto();
    [/highlight]

    Comment


    • #3
      Wenn ein Objekt vom Typ Auto nicht riesig groß ist und man nicht sehr viele davon braucht, droht kein Stack-Überlauf, und dann würde ich im Zweifelsfall das Objekt auf dem Stack anlegen.

      Beim Arbeiten mit der Halde (=Heap) können verschiedene Probleme auftreten, die man ansonsten nicht hat:

      - man kann vergessen, die Objekte mit dem delete Operator wieder freizugeben, dann hat man sich ein Speicherleck gebaut (manchmal ist aber auch ein Garbage-Kollektor vorhanden, der unbenutzte Haldenobjekte automatisch freigibt).

      - wenn das Programm lange läuft und viel mit der Halde arbeitet (viele Objekte anlegt und wieder freigibt), dann kann die Halde allmählich fragmentieren, d.h. der unbenutzte Haldenspeicher ist zerstückelt, und das Anlegen neuer Objekte wird schwieriger und dauert länger; im Extremfall geht es gar nicht mehr. (hängt aber glaube ich von der Variante der Freispeicherverwaltung ab)

      Darum würde ich nur mit der Halde arbeiten, wenn es dafür auch einen Grund gibt, z.B. wenn man ein Array mit zur Laufzeit veränderbarer Größe realisieren will.

      Comment


      • #4
        (manchmal ist aber auch ein Garbage-Kollektor vorhanden, der unbenutzte Haldenobjekte automatisch freigibt).
        Wo sollte es diesen geben?


        hängt aber glaube ich von der Variante der Freispeicherverwaltung ab)
        Was könnte das sein? Betriebssystem?
        Christian

        Comment


        • #5
          Wo sollte es diesen geben?
          Das hängt vom Compiler ab, ob ein Garbage-Collector (= automatische Speicherbereinigung) vorhanden ist. Ich weiß jetzt nicht, ob es das für C bzw. C++ überhaupt gibt, aber es ist auf jeden Fall die Ausnahme.

          Was könnte das sein? Betriebssystem?
          Ich glaube, meistens holt sich die Anwendung den Freispeicher vom OS in größeren Portionen und unterteilt diese dann selbst in die Einheiten, die der Programmierer mit malloc() / new angefordert hat. Dafür gibt es verschiedene Methoden, zum Beispiel eine Freispeicherliste: jeder freie Speicherabschnitt bildet einen Knoten dieser Liste, und enthält die Angabe, wie groß er ist, und einen Zeiger auf den nächsten freien Abschnitt.

          Ich kenne auch die Technik, dass der Freispeicher in Blöcke von z.B. 16 Byte eingeteilt ist, und in einem zusätzlichen Speicherbereich gibt es für jeden dieser Blöcke ein Bit, das angibt, ob derb Block frei ist. Das hat den Vorteil, dass aufeinenderfolgende Speicherabschnitte bei der Freigabe automatisch wieder zu einem durchgehenden freien Bereich zusammengefügt werden.
          Bei der Freispeicherliste ergibt eine vom Benutzer freigegebene Speicherportion immer einen neuen Listenknoten, und es ist schwierig, die im Speicher unmittelbar aneinander anschließenden Knoten zu erkennen und zu einem einzigen zu vereinigen.

          Comment


          • #6
            Richtig, in C/C++ gibt es keine Garbagecollectors. Und in anderen Sprachen NET, JAVA usw. ist es nicht die Ausnahme, sondern die Regel.

            Und wie das Betriebssyytem den Speicher verwaltet kann egal sein, da du eh nicht ändern kannst. Irgendwelche Powertools die den Speicher defragmentieren halt ich für Humbug.
            Christian

            Comment


            • #7
              Das Wichtigste ist dass man ein Objekt eventuell in mehreren Funktionen oder Klassen verwendet, Parameterübergabe oder es ist sogar nötig es global zu halten. Dann ist der Weg mit new besser. z.B. ein Bild das während der Laufzeit im Speicher gehalten wird und eventuell neu geladen wird kann dann zuerst mit delete freigegeben werden damit keine Speicherlecks entstehen.
              Das Selbe wenn z.B. in einer Schleife Objekte erzeugt werden und der Block nicht verlassen wird; da kann der Speicher voll werden. Wird aber *meinAuto=new Auto(); verwendet kann nach der Verwendung in der Schleife delete meinAuto; geschrieben werden bevor ein neues Objekt instanziert wird. Somit gibt es auch wirklich nur eines.
              Wichtig: nach delete darf nicht mehr auf den Zeiger zugegriffen werden, aus dem ganzen Programm nicht. Man kann nach delete auch meinAuto=NULL schreiben und dann jeweils vor dem Löschen und ggf. vor der Verwendung mit if(meinAuto) prüfen ob das Objekt nicht NULL ist.

              Comment

              Working...
              X