Zeigerzuweisung mit new: Bleibt der alte Zeiger erhalten?



  • Hi,
    wenn ich das hier mache

    testklasse *erster=new testklasse();
    erster=new testklasse();
    

    habe ich zweimal eine testklasse auf dem Arbeitsspeicher angelegt.

    Wird die erste mit new angelegte testklasse durch irgendwelche Destruktoren während der Laufzeit des Programms zerstört?

    Ich benutze wxwidgets und es kommt vor, dass manche Variablen in der Testklasse Zufallswerte erzeugen bzw. mein Programm abstürzt.



  • new ohne delete => Speicherleck!



  • Nein. Der Desktruktor wird je erst über delete aufgerufen. Hast also nen Memory-Leak.



  • Hm...dann ergeben sich aber zwei Fragen: Wenn das Programm keinen Zeiger mehr auf den Speicher hat, kann der Speicher überschrieben werden?

    Und wenn ich den Zeiger gesichert habe, kann dann irgend ein anderes Programm hergehen und die Stelle im Speicher überschreiben?

    Ich bin grad am rätseln, warum die Variablen der angelegten Testklassen hin und wieder Zufallswerte bekommen. Wäre schön, wenn ich diese Möglichkeit ausschließen kann.



  • Jedes Programm hat seinen eigenen Speicher. Das heisst, dass ein anderes Programm nicht einfachso deinen Speicher überschreiben kann.

    Wenn du jetzt Speicher anforderst, den Zeiger verlierst, dann bleibt der Speicher reserviert und (dein eigenes Programm) wird den Speicher nicht mehr überschreiben.

    Erst, wenn dein Programm beendet wird, wird der Speicher vom OS aufgeräumt.



  • solange du keinen delete ausführst ist der Speicher weiterhin reserviert.... Wenn du Glück hast ist das Betriebssystem so intelligent, den Speicher wieder freizugeben, wenn du das Programm beendest, aber davon sollte man nicht ausgehen.

    C(++) hat keinen Garbage-Collector... wenn du Speicher anforderst, musst du ihn auch wieder zurückgeben

    Und wenn die Variablen deiner Klasse zufällige Werte haben, dann solltest du sie im Konstruktor evtl erstmal initialisieren... ein int a; cout << a << endl; ist nunmal undefiniert


  • Mod

    Big_Exception schrieb:

    Hm...dann ergeben sich aber zwei Fragen: Wenn das Programm keinen Zeiger mehr auf den Speicher hat, kann der Speicher überschrieben werden?

    Falls niemand einen Zeiger auf das Objekt hat, sicher. Natürlich wirst du diesen Fall niemals beobachten können, denn zur Erkennung müsstest du ja doch einen Zeiger behalten haben, was die Wiederverwendung wiederum ausschließen würde...

    Und wenn ich den Zeiger gesichert habe, kann dann irgend ein anderes Programm hergehen und die Stelle im Speicher überschreiben?

    Grundsätzlich sind die Adressräume von verschiedenen Programmen unterschiedlich (wir gehen mal von einem modernen Betriebssystem aus, nicht sowas wie DOS). Es ist schlicht unmöglich, auf den Speicher eines anderen Programmes zuzugreifen, es sei denn, man umgeht den Speichermanager auf Kernelebene oder es handelt sich von vornherein um shared Speicher. Für ganz gewöhnlichen Speicher in ganz gewöhnlichen Anwendungen spielt das keine Rolle.



  • Big_Exception schrieb:

    Wenn das Programm keinen Zeiger mehr auf den Speicher hat, kann der Speicher überschrieben werden?

    So wie ich deine Frage verstanden habe: Sobald kein Zeiger mehr auf einen dynamisch (mit new ) allokierten Speicherbereich zeigt, hast du ein Memory Leak. Das heisst, der angeforderte Speicherplatz bleibt zwar besetzt, aber du kannst nichts mehr mit ihm anfangen. Deshalb immer delete auf Zeiger ausführen, wenn deren mit new angeforderter Speicherplatz nicht mehr benötigt wird.



  • //Speicher allokieren und speicheradresse auf Pointer1 zeigen lassen
    testklasse *Pointer1= new testKlasse();
    
    //Pointer2 die Speicheradresse von Pointer1 zuweisen
    testklasse *Pointer2= Pointer1;
    
    //Pointer1 mit neuer Speicheradresse mit neu allokiertem speicher zuweisen
    Pointer1= new testKlasse();
    

    hier merkst du dir die speicheradresse der ersten Speicherallokation im Pointer2, und kannst nun Pointer1 überschreiben. später kannst du mit delete , beide speicehrbereichen mit Pointer1 und Poitner2 löschen...

    hoffe dir ist das jetzt klarer



  • Ja, der Speicher kann überschrieben werden. Und er kann auch wieder freigegeben werden. Aber das ist kein definiertes Vorgehen, daher passiert das nur bei:
    a) schlechtem Design
    b) Programmierfehler.

    Zu a gehört sowas:

    int *a = new int(1);
    int *b = new int(2);
    b = 0;
    delete (a+1);
    

    Zu b gehört sowas:

    char a[] = "narf";
    int *b = new int(1);
    b = 0;
    strcpy(a, "narf2");
    

    Hier ist *b dann 0.



  • Big_Exception schrieb:

    Ich bin grad am rätseln, warum die Variablen der angelegten Testklassen hin und wieder Zufallswerte bekommen.

    Das kann nichts damit zu tun haben dass du keinen Zeiger auf den reservierten Bereich mehr hast. Denn wenn du keinen Zeiger drauf hast kannst du auch keien Werte von dort bekommen und damit können die Zufallswerte auch nicht von dort kommen. Ich tippe daher auch auf nicht erfolgte Initialisierungen.

    P.S.: ja, mit irgendwelcher Pointer-Arithmetik könnte man aus Versehen vielleicht wieder auf den "verlorenen" Speicherbereich kommen. Dazu müsste man aber schon böswilligen oder absolut sinnfreien Code schreiben. Davon geh ich mal (trotz Speicherleck) nicht aus.


Anmelden zum Antworten