Anfänger braucht kurz hilfe



  • hallo erstmal hoffentlich bin ich hier richtig 🙂

    ich hab für mich ein projekt in MSVS2008 erstellt um mir die gelehrten inhalte aus meinem c++ buch zu festigen
    ... ist also alles auf meinem mist gewachsen 😛

    so nun zum problem:
    ein niemals erstelltes objekt wird zerstört!?

    hier der wichtige ausschnitt aus main.cpp

    ...
        //Elementzeiger
        Test_Class_A classA(50);
    	attribute_A_ptr = &at_a;
    	ptrA = &classA;
    	//für attribute ... nicht benutzbar da attribute private
    	//int Test_Class_A::*int_ptr = &Test_Class_A::attribute_A;
    
    	//für methoden
    	void (Test_Class_A::*ptr_methoden)(int* ptr) = &Test_Class_A::get_attribute_A;
    
    	// (classA.*ptr_methoden)(attribute_A_ptr);    //oder
    	(ptrA->*ptr_methoden)(attribute_A_ptr);
    	cout << *attribute_A_ptr << "\n";
    	attribute_A_ptr = NULL;
    	ptr_methoden = NULL;
    
    	delete &classA; //geht nicht im debug-mode ... im release-mode wird am ende ein niemals erstelltes objekt zerstört??
    ...
    

    hab das projekt hier mal hochgeladen
    mediafire:
    http://www.mediafire.com/?1azondgzonx



  • will mir niemand helfen?

    zur erklärung die klasse Test_Class_A:

    // Test_Class_A.h
    
    #ifndef _Test_Class_A_
    #define _Test_Class_A_
    
    class Test_Class_A {
    	private:
    		int attribute_A;
    
    	public:
    		Test_Class_A ();
    		Test_Class_A (int attribute_A);
    		~Test_Class_A ();
    		void set_attribute_A (int attribute_A);
    		void get_attribute_A (int* attribute_A);
    };
    
    #endif
    
    // Test_Class_A.cpp
    
    #include <iostream>
    #include "Test_Class_A.h"
    using namespace std;
    
    Test_Class_A::Test_Class_A () {
    	this->attribute_A = 0;
    	cout << "<Test_Class_A> objekt created\n"; 
    }
    
    Test_Class_A::Test_Class_A (int attribute_A) {
    	this->attribute_A = attribute_A;
    	cout << "<Test_Class_A> objekt created\n"; 
    }
    
    Test_Class_A::~Test_Class_A () {
    	cout << "<Test_Class_A> objekt destroyed\n";
    }
    
    void Test_Class_A::set_attribute_A (int attribute_A) {
    	this->attribute_A = attribute_A;
    }
    
    void Test_Class_A::get_attribute_A (int* attribute_A) {
    	*attribute_A = this->attribute_A;
    }
    

    wobei in main

    int at_a = 0;
    int* attribute_A_ptr = &at_a;
    

    und dann

    ...
        //Elementzeiger
        Test_Class_A classA(50);
    	attribute_A_ptr = &at_a;
    	ptrA = &classA;
    	//für attribute ... nicht benutzbar da attribute private
    	//int Test_Class_A::*int_ptr = &Test_Class_A::attribute_A;
    
    	//für methoden
    	void (Test_Class_A::*ptr_methoden)(int* ptr) = &Test_Class_A::get_attribute_A;
    
    	// (classA.*ptr_methoden)(attribute_A_ptr);    //oder
    	(ptrA->*ptr_methoden)(attribute_A_ptr);
    	cout << *attribute_A_ptr << "\n";
    	attribute_A_ptr = NULL;
    	ptr_methoden = NULL;
    
    	delete &classA; //geht nicht im debug-mode ... im release-mode wird am ende ein niemals erstelltes objekt zerstört??
    ...
    

    als release gestartet passiert das:
    http://www.abload.de/img/printqxvc.jpg
    die letzte zeile ergibt keinen sinn
    es werden 3 <Test_Class_A> objekt created
    und 4! <Test_Class_A> objekt destroyed

    wieso wir der destructor nochmal aufgerufen bzw. warum stürzt die debug variante bei/nach der zeile

    delete &classA;
    

    ab

    PS: wenn ich hier falsch bin kann mir das ja auch mal jemand sagen
    oder ein admin den thread verschieben



  • ok habs rausgefunden ..

    delete kann nur auf objekte die mit new erzeugt werden angewendet werden (also die vom garbagecollector verwaltet werden)

    also

    delete &classA;
    

    ersetzen durch

    classA.~Test_Class_A();
    

    jetzt läuft auch die debug variante ohne fehler
    aber
    es wird immer noch am ende der destructor nocheinmal aufgerufen

    wahrscheinlich passiert das da ich vorher schon einmal ein objekt vom typ Test_Class_A mit new erstellt und delete zerstört hatte



  • classA.~Test_Class_A();
    

    den Destruktor einer Klasse rufst du nie selbst auf, das wird automatisch beim zerstören des Objektes gemacht, also entweder beim durchlaufen von delete wenn mit new erstellt wurde oder beim verlassen des gültigkeitsbereiches wenn das Objekt auf dem Stack liegt. Also das hast du bestimmt nicht so aus einem buch gelernt



  • danke !
    daran hatte ich gar nicht mehr gedacht ...
    mir ging es darum das objekt genau dann zu zerstören wenn ich es will, obwohl ich es ohne garbagecollector erstellt hatte

    ->den abschnitt in blockklammern gefasst und es geht
    nochmal danke



  • Hallo,

    garbagecollector?? Das Wort fällt doch nicht wirklich in deinem Buch im Zusammenhang mit new ? Einen solchen gibt es nicht in C++, auch nicht, wenn man Objekte mit new erstellt, da garbage collection eine "automatische" Speicherbereinigung impliziert, die gerade bei new nicht gegeben ist: Objekte, die mit new erstellt wurden, müssen mit delete per Programmcode gelöscht werden (kein Automatismus), sonst bleibt der Speicher belegt.

    MfG,

    Probe-Nutzer



  • Hallo

    Doch bei Managed C++... da gibt es den Garbagecollector ...
    http://de.wikipedia.org/wiki/C%2B%2B/CLI

    Das ist aber nicht das C++ was hier im Forum behandelt wird.

    Geht es in deinem Buch um Manged C++ ??
    Dann ist Forum eher richtig "C++/CLI mit .NET"

    Grüße



  • Ach jetzt glaub ich verstehe ich warum Release-Mode der Fehler kommt.

    Du nutzt C++/CLI richtig ?

    Ok da verhält sich die GarbageCollection im ReleaseMode anders als im Debug Mode.
    Im DebugMode wird ein Object erst dann freigegeben(eigentlich zur Freigabe markiert) wenn es den Scope verlässt...
    In deinem Fall:
    Bsp.

    {
    	Test_Class_A classA(50); 
    	// tu was 
    	// tu was 
    	// tu was 
    	// tu was 
    
    } // <- hier wird dein Objekt freigegeben. weil es nicht mehr benutzt wird.
    

    Im ReleaseModus gibt es eine Optimierung. Nämlich das Objekt wird sofort freigegeben wenn keiner mehr darauf zugreift.
    Bsp:

    {
    	Test_Class_A classA(50); 
    	// tu was 
    	// tu was 
    	(ptrA->*ptr_methoden)(attribute_A_ptr); // <- hier wird dein Objekt freigegeben. weil es nicht mehr benutzt wird. 
    	// ich gehe davon aus dass du jetzt nichts mehr classA anfasst.
    	// tu was 
    	// tu was 
    
    	// delete &classA;  daher schlägt das jetzt fehl weil es nicht mehr exitiert. Im Debugmodus hat es noch exitiert. 
    }
    

    Irgendwie verständlich ??
    Aber wirklich Freigeben wird es erst wenn der GC vorbei kommt.

    Grüß
    Martin


Anmelden zum Antworten