verständnissfrage zu delete



  • hi
    ich habe ein paar fragen zu delete:
    1.

    void *a=new vector<int>;
    delete a;
    

    wird hier der ganze vector gelöscht?
    wenn ja wird der destruktor des vektors aufgerufen?

    void *a=new vector<int>;
    vector<int> *delp=(vector<int> *) a;
    delete delp;
    

    wird hier der ganze vector gelöscht?
    wenn ja wird der destruktor des vektors aufgerufen?

    schonmal danke



  • 1. undefiniertes Verhalten
    2. ja, ja



  • Barcode schrieb:

    hi

    void *a=new vector<int>;
    delete a;
    

    wird hier der ganze vector gelöscht?
    wenn ja wird der destruktor des vektors aufgerufen?

    1. Nein
    2. erübrigt sich

    void *a=new vector<int>;
    vector<int> *delp=(vector<int> *) a;
    delete delp;
    

    wird hier der ganze vector gelöscht?
    wenn ja wird der destruktor des vektors aufgerufen?

    1. Ja
    2. Ja, sonst würde am Ende was vom Vector übrig bleiben (der allozierte Speicher)



  • Probier sowas doch selbst aus. Ob die Klasse vector<int> oder foo heißt, ist ja egal.

    struct foo
    {
    	~foo()
    	{
    		cout << "Destruktor" << endl;
    	}
    };
    
    int main()
    {
    	void *p1 = new foo;
    	delete p1;
    
    	cout << "p1 freigegeben" << endl;
    
    	void *p2 = new foo;
    	foo *p2_foo = static_cast<foo*>(p2);
    	delete p2_foo;
    
    	cout << "p2 freigegeben" << endl;
    }
    

    Ausgabe:

    p1 freigegeben
    Destruktor
    p2 freigegeben
    


  • ok danke an alle

    @ ipsec
    .....stimmt hast recht



  • Im yweiten Beispiel hast du Yeiger im Vector. Diese Yeiger werden nicht automatisch freigegeben. Das mußt du selber vor dem clear/dtor Aufruf machen.



  • ipsec schrieb:

    Probier sowas doch selbst aus.

    Wenn an allen Ecken und Enden der Programmiersprache undefiniertes Verhalten lauert, ist Ausprobieren keine gute Idee.
    Sobald man in den Bereich des undefinierten Verhaltens kommt, sind durch Ausprobieren gewonnene Erkenntnisse im besten Fall nutzlos.



  • Probier sowas doch selbst aus. Ob die Klasse vector<int> oder foo heißt, ist ja egal

    Wobei "ausprobieren" nicht reicht. Nur weil etwas geht, weils die aktuelle Implementation gerade so macht, heisst noch lange nicht, dass es vom C++ Standard her ok ist.

    Also: Ausprobieren ist gut, im Standard nachlesen noch besser...



  • Bashar schrieb:

    1. undefiniertes Verhalten

    Wieso zeigt das 1. Beispiel undefiniertes Verhalten?
    Der delete-Operator nimmt einen void* als Parameter. Oder sehe ich da was falsch?

    Hättest du vielleicht einen Artikel, wo ich mir das durchlesen könnte?



  • Das kannst du direkt im Standard unter 5.3.5§3 nachlesen, oder auch in der daranhängenden Fußnote:

    This implies that an object cannot be deleted using a pointer of type void* because there are no objects of type void.



  • ÄhhhWTF?! schrieb:

    Wieso zeigt das 1. Beispiel undefiniertes Verhalten?
    Der delete-Operator nimmt einen void* als Parameter. Oder sehe ich da was falsch?

    Du mußt unterscheiden zwischen der Funktion

    void operator delete(void*)
    

    , die Du schreiben kannst und damit das Speichermanegement implemenmtierst,

    und dem, was bei

    delete x;
    

    tatsächlich erzeugt wird, nämlich

    x.~X();//Destruktor aufrufen
    operator delete((void*)x);//Danach erst den Speicher weghauen
    


  • hey volkard,

    korrigier mich bitte falls ich falsch liege.

    das heißt wenn ich

    void* ptr = new myClass;
    

    schreibe und das objekt mittels delete lösche

    delete ptr;
    

    weiß der Compiler nicht welchen Desktruktor er aufrufen soll. Und versucht sowas zu generieren.

    ptr.~void(); // Klasse void existiert nicht -> Compilerfehler
    operator delete((void*)ptr);
    


  • > x.~X();//Destruktor aufrufen

    Er meint natürlich x->~X(); Denn das hat zur Folge: (*x).~X(); ---> Dereferenzieren von void* ist ungültig.


Anmelden zum Antworten