Speicher im vector freigeben und zwei weiterer Fragen



  • Hallo,
    ich habe eine Klasse Foo:

    class Foo
    {
    public: 
    int a;
    bool b;
    };
    

    Weiterhin gibt es einen vector<Foo*> v, der Zeiger auf Instanzen der Klasse aufnehmen soll.
    Eine Methode "New" erstellt eine neue Instanz und initialisiert sie. Anschliessend wird ein
    Zeiger auf den Speicherbereich der Instanz in v gepusht:

    void New()
    {
     Foo* p=new Foo;
     p->a=5;
     p->b=true;
     v.push_back(p);
    }
    

    Eine Release-Funktion soll sämtlichen allokierten Speicher freigeben.
    Dazu lösche ich jedes Element des vectors:

    void release()
    {
     int size=v.size();
     for(int n=0;n<size;n++)
       delete v[n];
    }
    

    Und genau da muss der Fehler stecken, da ich, sobald mehr als ein Element im Vector ist,
    eine Speicherzugriffsverletzung erhalte ("Die Anweisung ... verweist auf Speicher ....
    Die Funktion "read" konnte nicht durchgeführt werden..." - kennt ihr ja bestimmt 😉
    Wobei ich allerdings nicht weiss, warum dieser Fehler entsteht.
    v enthält doch Zeiger auf Speicherbereiche, die in der New-Methode allokiert wurden.
    Mit delete lösche ich doch den Speicherbereich, auf den ein Zeiger zeigt.
    Also sollte das doch möglich sein.
    Dann enthält v nur noch Zeiger, die auf keinen Speicherbereich mehr zeigen. ahhh, ja wahrscheinlich ist
    das der Fehler, oder?
    Andererseits: Wie kann ich die Speicherbereiche löschen?
    Der Destruktor vom vector wird das doch bestimmt nicht für mich übernehmen, oder?

    Eine weitere Frage:
    Ist es in so einem Fall sinnvoller, einen vector zu bilden mit Zeigern auf die Klasse und für
    jede Instanz selbst Speicher zu allokieren, oder ist es besser, den vector gleich vom Typ foo
    (vector(foo) v) zu machen?
    Dann würde die New()-Funktion so ausschauen:

    void New()
    {
     Foo f;
     f.a=5;
     f.b=true;
     v.push_back(f);
    }
    

    ...don't know...

    Noch eine dritte Frage:
    Ich benötige prinzipiell nur Strukturen, habe mich aber für eine Klasse entschieden, da ich im
    Ctor mit 0 initialisieren kann. Das ist jedoch nicht wichtig. Also, was wählt man hier?
    Schliesslich sind alle meine Members public - und sollen es auch bleiben, da ich wie gesagt nur ne
    Struktur benötige.
    Also, Klasse als Struktur getarnt oder gleich Struktur 🙂 ?
    Dankeschön für's lesen dieser langen Fragestellung und für eventuelle Antworten 😉
    Gruß
    E-the-Real

    edit: "int i" in "int n" verändert, da v[i] nicht dargestellt wurde ([i]=italic)



  • Also bei mir läuft dein Konstrukt, gemäss deinem Beispielcode ohne Probleme. Das heisst, n-mal New => n-mal Foo-Destruktor. Und natürlich auch kein Absturz. Da muss wohl ein Fehler in deinem restlichen Code stecken. 🙂
    Wenn möglich würde ich keine Zeiger im Vektor ablegen sondern die Objekte selbst. Das hängt jedoch ausschliesslich von deiner Anwendung ab. Dazu hast du jetzt allerdings nicht allzuviel erzählt.
    Wenn es wirklich Zeiger sein müssen dann wiederum würde ich Smart-Pointer verwenden. Da auto_ptr nicht möglich ist, kannst du stattdessen shared_ptr aus boost verwenden.

    mfg JJ



    1. Die beiden Funktionen sind in Ordnung, du machst also irgendwas zwischendurch mit dem Vektor (Speicherüberschreibung) und das gefällt dem delete dann nicht.

    2. Wenn du keine Polymorphie benötigst dann ist es sinnvoller direkt einen vector<Foo> zu erstellen, weil du dich dann nicht um die Speicherverwaltung kümmern musst!

    3. Eine Klasse als Struktur zu missbrauchen macht imho keinen Sinn! Wenn du wirklich eine Struktur brauchst, dann nimm sie auch! Strukturen sind IMHO nicht veraltet, weil man sie zu C Zeiten benutzt hat...



  • KPC schrieb:

    1. Eine Klasse als Struktur zu missbrauchen macht imho keinen Sinn! Wenn du wirklich eine Struktur brauchst, dann nimm sie auch! Strukturen sind IMHO nicht veraltet, weil man sie zu C Zeiten benutzt hat...

    😕
    Es gibt keinen unterschied, sie sind äquivalent. Was gibts da zu mißbrauchen?



  • randa schrieb:

    😕
    Es gibt keinen unterschied, sie sind äquivalent. Was gibts da zu mißbrauchen?

    Bei Strukturen sind standardmäßig alle Elemente public und man benutzt sie normalerweise um eine Reihe von Variablen die zueinander gehören, zu kapseln.
    Wenn ich also eine Klasse wie folgt schreibe:

    class Foo
    {
    public:
    //Nur Datenelemente, keine Methoden
    };
    

    dann ist das für mich ein Missbrauch der Klasse, weil man sie normalerweise nicht so benutzt, genau dafür gibt es Strukturen.



  • Vielleicht machst du das ganze zweimal ohne den vector selbst zu leeren? Ich würde in die release() Funktion zumindest noch ein v.clear() hinzufügen.



  • ich bin mir des public-private unterschieds bewusst, aber es ist doch blödsinn, hier von mißbrauch in diesem Zusammenhang zu sprechen. Es könnte jeder für alles struct nehmen, ohne Probleme.
    Ich zum Beispiel benutze structs nur als Ansammlung von Daten, gekapselt in einer Instanz, während ich Klassen als Typen und Konzepte verwende. Aber er könnte genauso class nehmen, völlig gleichgültig. Ich wüsste nicht, wo dazu jemand vorschriften gemacht hat.



  • Hallo,

    das ist Ansichtssache. Ich denke, dass es zum guten Programmierstil gehört, das Mittel zu nutzen, was am ehesten das Gewünschte ausdrückt. Lies dir das mal durch:
    http://www.artima.com/intv/goldilocks3.html



  • Hallo, erstmal thx für die Antworten.
    Ich habe mittlerweile den Fehler gefunden:
    In der main-Fkt. wurde drei mal New aufgerufen und drei mal release, aber die release
    muss/darf nur einmal aufgerufen werden, da sie ja den ganzen vector durchgeht.
    Zum Programm an sich:
    Ich wollte eine Art Buchhaltungssoftware schreiben, bei der man neue Datensätze
    (=Buchungen) eingeben kann (in der New-Methode würden dann die Eingaben zugewiesen werden
    und keine Konstanten wie im Beispiel), die im vector verwaltet werden.
    Ich werde das wahrscheinlich mit MFC realisieren (leider, ich mach's auch nicht gerne,
    aber dafür sind die eigentlich ganz gut geeignet und ich muss das Gerüst nicht selber schreiben)
    Ein Tabellen-Steuerelement soll dann eine Übersicht über alle vorhandenen Buchungen führen.
    Damit ich schnell manövrieren kann, werden sämtliche Buchungen in einen vector gepusht.
    Und da habe ich halt überlegt:
    Ist es sinnvoller/schneller, den vector klein zu halten und nur die Zeiger zu pushen oder
    sollte ich gleich jede Buchung als Instanz einer Klasse bzw. Struktur pushen, so dass der vector
    dann direkt die Instanzen beinhaltet?

    Dadurch wird der vector natürlich wesentlich größer.
    Von der Speicherverwaltung macht das doch imho keinen Unterschied, da sowohl vector als auch new auf dem
    Heap anlegen, oder?
    Was also tun? Zeiger in vector oder gleich die Objekte?
    Gruß



  • Sicherer ist es die Objekte im Vektor zu speichern. Du brauchst dir dan halt keine Gedanken um die Speicherverwaltung zu machen.
    Wenn du Zeiger verwenden musst, dann solltest du Smart-Pointer verwenden.

    mfg JJ



  • Gleich die Objekte. Is einfacher zu benutzen und du brauchst eh keine Polymorphie.


Anmelden zum Antworten