Problem mit Speicherbereinung via delete



  • In folgende Pseudocode erstelle ich in einer Funktion via new ein Objekt, wessen Zeiger in main() weiterverwendet werden soll. Doch nach Erfüllung des Zweckes und dem darauffolgenden "delete"-Aufrufes befindet sich das Objekt augenscheinlich noch immer im Speicher, wie die untenstehende Ausgabe verdeutlicht.

    Object *create_new_obj() {
    	Object *new_obj = new Object;
    
    	return new_obj;
    }
    
    int delete_obj(Object *obj) {
    	delete obj;
    	obj = NULL;
    	return 0;
    }
    
    int main(void) {
    	Object *obj = create_new_obj();
    	printf("machwas1: %i\n", obj->machWas());
    
    	delete_obj(obj);
    
    	printf("machwas2: %i\n", obj->machWas());
    
    	return 0;
    }
    

    Ausgabe:

    machwas1: 23
    machwas2: 23
    

    Allem Anschein nach wird nicht das eigentliche Objekt gelöscht, sondern vielmehr nur eine Kopie. Kann mir jemand behilflich sein und mir auf die Sprünge helfen, wie ich das dynamisch erstellte Objekt wieder (sauber) entfernen kann?

    mfg Stefan



  • Ist doch entfernt, nur der Zeiger zeigt halt noch drauf.



  • Sollte er aber nicht... oder hab' ich da was falsch verstanden?

    obj = NULL;
    


  • Hallo

    benutzt den Debugger.
    Dann wirst du sehen, das du nur den lokalen Zeiger obj in der Funktion delete_obj auf NULL setzt.
    Davon ist aber nicht der zeiger obj aus der main-Funktion betroffen, der besitzt seine Adresse noch. Und dort wird danach ein unerlaubter Zugriff auf einen ungültigen Speicherbereich ausgeführt. Das kann gutgehen, wird es aber meistens nicht.

    bis bald
    akari



  • Welches Verhalten erwartest du denn von deinem Code?



  • ..., dass es beim zweiten machWas in einem Segmentation Fault beendet wird, um sicher zu gehen, dass die Variable obj und damit einhergehend der Speicher der Attribute des Objekts und des Objekts an sich leer ist.

    Wichtig für mich wäre eben, dass main() unberührt von "obj = NULL" und ähnlichem bliebe, deshalb auch die Auslagerung in Funktionen.



  • Offenbar übergibt die Speicherverwaltung aus Effizienzgründen den Speicher nicht sofort wieder an das System zurück 😉 will heissen wenn Du später neue Objekte erzeugst und _dann_ wieder auf den "toten" Pointer zugreifst dürften unschöne Dinge passieren...

    Merke: Das Verhalten beim Zugriff auf nicht-allokierten Speicher ist _undefiniert_, d.h. es gibt nicht zwangsläufig irgendeinen Fehler, sondern es passiert wahrhaft _irgendwas_!



  • Stefan_Guest schrieb:

    ..., dass es beim zweiten machWas in einem Segmentation Fault beendet wird, um sicher zu gehen, dass die Variable obj und damit einhergehend der Speicher der Attribute des Objekts und des Objekts an sich leer ist.

    Wichtig für mich wäre eben, dass main() unberührt von "obj = NULL" und ähnlichem bliebe, deshalb auch die Auslagerung in Funktionen.

    Da du nur eine Kopie des Zeiger änderst, musst die eine Reference oder einen Zeiger auf den Zeiger an die Funktion übergeben. Das sähe dann ungefähr so aus:

    int delete_obj(Object *&obj) {
        delete obj;
        obj = NULL;
        return 0;
    }
    

    mfg.


Anmelden zum Antworten