vector auf dem Heap



  • Hallo zusammen,

    vector<T>* p = new vector<T>;
    

    So reserviere ich mir Speicher auf dem Heap für einen vector. Sind die Elemente die ich jetzt mittels push_back in den vector schiebe auch auf dem Heap oder sind die wieder lokal?

    kann ich hiermit

    delete p;
    

    den Speicher wieder frei geben oder muss ich

    delete[] p;
    

    verwenden?

    Gruß Spartaner



  • vector allokiert Standardmäßig immer auf dem Heap. Wenn du das ändern willst, dann musst du den Allocator ändern (siehe Doku zu std::vector).

    Was du machst ist _ein_ Objekt anzulegen von std::vector (was wohl nur eingeschränkt Sinn machen dürfte). Also musst du auch nur den delete-op und nicht den delete[]-op anlegen.

    btw. std::vector<T,...> ist eine ganz normale Template-C++-Klasse. Da ist keine Magie-Hinter und die Klasse ist auch nicht in der Sprache eingebaut, sondern nur eine Library Sache!



  • Hallo

    Sind die Elemente die ich jetzt mittels push_back in den vector schiebe auch auf dem Heap

    Die Kopien im vector sind auf dem Heap.

    kann ich hiermit...
    den Speicher wieder frei geben

    Ja. Du must den normalen delete-Op anwenden. vector verwaltet seine Elemente selber, manuell die Elemente löschen ist nicht nötig.

    Das gilt natürlich nur für die Elemente selber. Wenn T in Wirklichkeit ein typedef auf ein Zeiger auf eine Klasse ist, müßen trotzallem noch die Instanzen auf die die Elemente verweisen gelöscht werden.

    Übrigens solltest du prüfen ob du wirklich ein vector auf dem Heap brauchst. Das macht in den meisten Fällen kaum Sinn.

    bis bald
    akari



  • Oh, da habe ich dann wohl was durcheinander gebracht.

    Habe gerade keine Compiler zur Hand, sonst hätte ich es einfach ausprobiert, deshalb die Frage.

    Wenn ich also in einer Funktion einen vector erstelle und dort ein paar Elemente rein schiebe, dann ist der vector auch noch außerhalb der Funktion gültig? Also könnte ich diesen anprechen, wenn die Funktion einen Zeiger auf den vector zurückgibt?

    EDIT: T ist bei mir einfach ein Klassentyp. Habe T einfach als Platzhalter verwendet.

    Gruß Spartaner



  • Akari hat nicht ganz unrecht. Da der Vektor seinen Speicher selbst verwaltet, liegt alles Wichtige ohnehin auf dem Heap. Und wenn der Vektor Member eine Klasse ist, und du Zeiger verwendest, liegt auch der "Rest" des Vektors auf dem Heap.

    Wenn du allerdings unbedingt mit einem Zeiger auf einen Vektor rumhantieren möchtest, bitte sehr 😉



  • Spartaner schrieb:

    Wenn ich also in einer Funktion einen vector erstelle und dort ein paar Elemente rein schiebe, dann ist der vector auch noch außerhalb der Funktion gültig? Also könnte ich diesen anprechen, wenn die Funktion einen Zeiger auf den vector zurückgibt?

    Nein, am Ende der Funktion werden alle lokalen Variablen aufgeräumt - und dabei auch der vector zerstört. Aber du kannst eine Kopie von ihm nach draußen weitergeben, die (eigenständig) bestehen bleibt.



  • Spartaner schrieb:

    ...

    Wenn ich also in einer Funktion einen vector erstelle und dort ein paar Elemente rein schiebe, dann ist der vector auch noch außerhalb der Funktion gültig? Also könnte ich diesen anprechen, wenn die Funktion einen Zeiger auf den vector zurückgibt?
    ...

    Nein, ist er nicht. Der Vektor ist dann ein lokales Objekt, dessen Destruktor beim Verlassen der Funktion aufgerufen wird, was einen Aufruf von "delete" für jedes Element des Vektors bedeutet.

    Wenn du allerdings den Vektor von aussen übergibst, und in der Funktion nur füllst, dann sind die Elemente, die jetzt im Vektor stehen, auch ausserhalb der Funktion noch gültig, da der Vektor eigene Kopien der Objekte anlegt.

    Das Problem: Wenn du den Vektor in einer Funktion auf dem Heap mittels new anlegst, und dann einen Zeiger zurückgibst, dann musst du dich ausserhalb der Funktion um die Freigabe des Speichers kümmern. Manchmal ist das der richtige oder einzige Weg, normalerweise ist es aber sinnvoll, einen zu füllenden Vektor ausserhalb der Funktion anzulegen und als Referenz zu übergeben.



  • Hallo

    Wenn ich also in einer Funktion einen vector erstelle und dort ein paar Elemente rein schiebe, dann ist der vector auch noch außerhalb der Funktion gültig? Also könnte ich diesen anprechen, wenn die Funktion einen Zeiger auf den vector zurückgibt?

    Auch vector muß sich an die Gültigkeitsregeln wie alle Variablen halten. Du kannst aber vector durchaus als Parameter und Rückgabewert verwenden, da vector sich und seine Elemente kopieren kann. Wenn mit Referenzen auf vector gearbeitet wird kann sogar das kopieren wenn unnötig vermieden werden.
    Für einen klassenweiten vector bietet sich stattdesen natürlich ein Member der Klasse an. Dort kann vector seine ganze Stärke ausspielen, weil mit dem Ende einer Klasseninstanz auch der vector und alle seine Elemente automatisch gelöscht werden.

    bis bald
    akari



  • Spartaner schrieb:

    Oh, da habe ich dann wohl was durcheinander gebracht.

    Habe gerade keine Compiler zur Hand, sonst hätte ich es einfach ausprobiert, deshalb die Frage.

    Wenn ich also in einer Funktion einen vector erstelle und dort ein paar Elemente rein schiebe, dann ist der vector auch noch außerhalb der Funktion gültig? Also könnte ich diesen anprechen, wenn die Funktion einen Zeiger auf den vector zurückgibt?

    Wie erstellst du ihn? Wenn du ihn auf dem Stack anlegst, wird er wie jedes andere Objekt auf dem Stack beim verlassen des Scopes (der Funktion) aufgeräumt. Du kannst aber zB eine Kopier zurück geben

    // Okay
    std::vector<T> okay() {
      std::vector<T> foo;
      foo.push_back(T());
      return foo;
    }
    
    void okay(std::vector<T> &v) {
      v.push_back(T());
    }
    
    // Nicht Okay
    std::vector<T> &nicht_okay() {
      std::vector<T> foo;
      foo.push_back(T());
      return foo;
    }
    
    void nicht_okay(std::vector<T> *v) {
      std::vector<T> vec;
      vec.push_back(T());
      v = &vec;
    }
    


  • Danke, ihr habt mir sehr geholfen! Ich habe mal wieder aus einem einfachen Problem ein viel zu großes gemacht.
    Ich werde jetzt einfach an die Funktion einen Zeiger auf meinen vector übergeben und ihn dann so befüllen.

    Danke und Gruß
    Spartaner


Anmelden zum Antworten