Löscht Vector Instazen meiner Klasse?



  • Die Frage ist, ob der Destructor eines Vektors auch die Instanzen der beinhalteten Klasse löscht, wie es hier passieren sollte und ob es einen besseren/stilvolleren Weg gibt um das gewünschte Ergebnis zu erzielen. Ich wollte dabei die Verwendung von Pointern vermeiden, um am Ende möglichst wenige Segfaults zu bekommen :p

    #include <vector>
    
    class A {};
    
    int main()
    {
    	std::vector<A> v;
    	{
    		A &a = *(new A);
    		v.push_back(a);
    	}
    } //Wurde a hier gelöscht?
    

    Vielen Dank schon mal im Voraus.



  • Die Frage ist, ob der Destructor eines Vektors auch die Instanzen der beinhalteten Klasse löscht,

    Ja. Aber Die Frage bei deinem Code ist, was sonst noch passiert.

    Edit:
    Hier noch genauer erläutert, dein Code ein wenig umgeschrieben:

    #include <vector> 
    
    class A {}; 
    
    int main() 
    { 
        std::vector<A> v; 
        { 
            A* p = new A;    // Objekt vom Typ A auf den Freestore erzeugen, p zeigt darauf.
            A &a = *p;       // Referenz auf das zuvor erzeugte Objekt initialisieren, noch wurde nichts kopiert oder gelöscht...
            v.push_back(a);  // Objekt Referenz wird an std::vector<A>::push_back(..) übergeben und dabei kopiert
        } // Die Referenz a wird ungültig, der Pointer p wird ungültig, das Objekt auf das p zeigte lebt weiter und kann nicht mehr erreicht werden. Es entsteht ein Memory Leak
    } // Das Objekt v wird zerstört und damit die Kopie worauf a und p einmal zeigten
    

    Edit2: Die Kommentare beziehen sich auf das veraltete C++03



  • Danke, die Frage an sich ist damit für mich beantwortet, auch wenn ich mit "ist a hier gelöscht" das Objekt und nicht die Referenz meinte. Da du sagst, dass sich die Kommentare auf C++03 beziehen, würde mich jetzt interessieren, worin dabei der Unterschied zu C++11 besteht.



  • Wenn ich es mir genau überlege besteht keinen Unterschied zu C++11. Im Hinterkopf hatte ich noch die Move Geschichte, welche hier aber nicht zum tragen kommt, da ein L-Value an push_back(..) übergeben wird.

    Wie auch immer, ich hoffe dir ist klar, dass dein Code so nicht gut ist.



  • @Encypruon
    Das Objekt wird nicht gelöscht, da im Vektor ja eine Kopie gespeichert wird. Die Kopie wird gelöscht, das ursprüngliche Objekt nicht. -> Leak



  • Encypruon schrieb:

    Die Frage ist, ob der Destructor eines Vektors auch die Instanzen der beinhalteten Klasse löscht,

    Ja klar. Aber du hast da trotzdem etwas missverstanden. Siehe unten.

    Encypruon schrieb:

    wie es hier passieren sollte und ob es einen besseren/stilvolleren Weg gibt um das gewünschte Ergebnis zu erzielen. Ich wollte dabei die Verwendung von Pointern vermeiden, um am Ende möglichst wenige Segfaults zu bekommen :p

    #include <vector>
    
    class A {};
    
    int main()
    {
    	std::vector<A> v;
    	{
    		A &a = *(new A);
    		v.push_back(a);
    	}
    } //Wurde a hier gelöscht?
    

    Vielen Dank schon mal im Voraus.

    Du hast hier ein Speicherleck. Das Objekt, auf das sich a bezieht, hast du im Freispeicher angelegt und bleibt da bis zum Programmende einfach hängen. Der Vektor speichert nicht eine Referenz auf dieses Objekt und gibt es hinterher frei, sondern er erzeugt eine Kopie des Objekts und gibt diese Kopie wieder frei. Um dein im Freispeicher erzeugtes Objekt musst du dich selbst kümmern. Dieses Programm ergibt relativ wenig Sinn. Ohne Speicherleck sieht es dann so aus:

    #include <vector>
    
    class A {};
    
    int main()
    {
    	{
    		std::vector<A> v;
    		A a;
    		v.push_back(a);
    	}
    	// hier gibt's kein A-Objekt mehr
    }
    

    Mir fallen eigentlich nur zwei Klassen aus der neuen Standardbibliothek ein, die sich so verhalten, wie du es von vector erwartet hattest -- also in dem Sinne, dass sie sich für das von dir allozierte Zeug "verantwortlich fühlen" und es für dich irgendwann freigeben: std::shared_ptr und std::unique_ptr. Alles andere ist "wertorientiert".

    Ggf. macht auch sowas Sinn:

    #include <vector>
    
    class A {};
    
    int main()
    {
    	{
    		std::vector<std::unique_ptr<A>> v;
    		std::unique_ptr<A> up (new A);
    		v.push_back(std::move(a));
    	}
    	// hier gibt's kein A-Objekt mehr
    }
    

    Das ist aber wahrscheinlich weniger praktisch, als du denkst.



  • Ich habs wohl nicht klar genug geschrieben... 🤡


Anmelden zum Antworten