Wert löschen nachdem es zurückgegeben wurde.



  • Hi,
    ich reservier in einer Funktion neuen Speicher, deren Inhalt dann allerdings zurückgegeben werden soll. Wie kann ich den Inhalt zurückgeben und erst danach freigeben?



  • Zeig mal den Code her, was du machen willst.



  • Das Freigeben ist Aufgabe des Aufrufers, und deshalb nicht unbedingt eine gute Möglichkeit. Kannst du deinen Zeiger nicht kapseln und in eine RAII-Klasse einbinden, sodass der Speicher im Destruktor freigegeben wird? Sonst reicht vielleicht auch ein Smart-Pointer. Oder wenn möglich natürlich direkt ein Stack-Objekt und keinen Zeiger zurückgeben.

    Oder du gehst halt den Weg über eine Freigabefunktion. Das Problem hierbei ist, dass das schnell mal vergessen geht.



  • Äh? Ich habe jetzt kein bisschen verstanden 😃



  • Lumio schrieb:

    Äh? Ich habe jetzt kein bisschen verstanden 😃

    😃 xD LOL!^^

    Aber auf die Idee, genau nachzufragen, kommst du nicht?



  • Ich versteh ganz einfach jeden einzelnen Begriff nicht:

    • Was bedeutet Zeiger kapseln und in eine RAII-Klasse einbinden?
    • Was meinst du mit Speicher im Destruktor freigegeben?
      Das erinnert mich an Klassen (hab ich in C++ noch nicht durchgenommen), wo es ja einen Destruktor gibt.
    • Was ist ein Smart-Pointer?
    • Was ist ein Stack-Objekt?
    • Freigabefunktion? Warum wird diese vergessen?

    😉



  • Lumio schrieb:

    Ich versteh ganz einfach jeden einzelnen Begriff nicht:

    • Was bedeutet Zeiger kapseln und in eine RAII-Klasse einbinden?
    • Was meinst du mit Speicher im Destruktor freigegeben?
      Das erinnert mich an Klassen (hab ich in C++ noch nicht durchgenommen), wo es ja einen Destruktor gibt.
    • Was ist ein Smart-Pointer?
    • Was ist ein Stack-Objekt?
    • Freigabefunktion? Warum wird diese vergessen?

    😉

    [ ] Du weisst, was eine Suchmaschine ist, und wie man sie benutzt.



  • äh... hm... hab ich nen Joker 😛

    Ja ne, is klar, aber hätte ja sein können, dass es mir jemand auf die schnelle beantwortet hätte.



  • Lumio schrieb:

    Das erinnert mich an Klassen (hab ich in C++ noch nicht durchgenommen), wo es ja einen Destruktor gibt.

    Dann hat es nicht sehr viel Sinn, wenn wir dir die anderen Konzepte erklären, da das Verständnis von Klassen dafür notwendig ist. Aber RAII beantwortet insofern deine Frage, als es ein in C++ sehr oft angetroffenes Konzept ist, um die Verantwortlichkeit für Freigaben und Aufräumarbeiten zu regeln.

    Lumio schrieb:

    Freigabefunktion? Warum wird diese vergessen?

    Deswegen:

    bool AnyFunction()
    {
       ... // ganz viel Code
       int* NewMemory = GetIntMemory(12); // deine Speicherfunktion, die new benutzt.
       ... // noch mehr Code, in dem NewMemory eingesetzt wird
       if (...)
          return true; // was ist mit NewMemory? -> Freigabe nicht vergessen.
    
       ... // NewMemory wird nun nicht mehr eingesetzt. Also holen wir neuen Speicher...
       NewMemory = GetIntMemory(21); // oh, da hätte man den alten Speicher freigeben müssen.
       ... // wieder viel Code
       return false;
    } // hier endet der Block, dran gedacht, NewMemory freizugeben?
    

    Das Beispiel ist vielleicht überspitzt, aber sowas geht schnell vergessen. Besonders, wenn die Funktion an vielen Stellen verlassen werden kann (evtl. auch durch Exceptions).



  • Lumio schrieb:

    Hi,
    ich reservier in einer Funktion neuen Speicher, deren Inhalt dann allerdings zurückgegeben werden soll. Wie kann ich den Inhalt zurückgeben und erst danach freigeben?

    Hi,

    meinst Du sowas?

    #include <string>
    
    std::string meineFunktion() {
       std::string Rueckgabe("Rückgabe"); // hier wird Speicher reserviert
       return Rueckgabe;
    }
    
    int main() {
       std::string mainVar;
    
       mainVar = meineFunktion(); // hier wird der Inhalt von "meineFunktion()::Rueckgabe" kopiert und dieser anschließend zerstört
    ...
    

    (Falls es Dir nicht um "Speicher für Buchstaben" geht: Das ist ein allgemeines Konzept, das auch mit int, vector<float>, ... und Alles Andere funktioniert)

    WENN das in etwa Deiner Frage entspricht, hast Du vermutlich sowas versucht:

    char* meineSchlechteFunktion() {
       char* Rueckgabe = new char[10];
       Rueckgabe[2] = 'a';
       return Rueckgabe;
       delete[] Rueckgabe; // Hoppla ... tut nicht..
    }
    
    int main() {
       char* mainVar;
       mainVar = meineSchlechteFunktion();
    ...
    

    Das klappt natürlich nicht, weil Du garantiert hoffst, dass mainVar hinterher auch auch Speicher zeigt ... und deshalb solltest Du ihn nicht wieder freigeben.

    Also musst Du den Ablauf beibehalten:
    a) Speicher in der Funktion allozieren (machen Dir Typen wie int, float, std::string, std::vector, ... ganz automatisch)
    b) Kopieren in durch main bereitgestellten Speicher
    c) danach erst zerstören des Speichers in der Funktion.

    Du darfst b) und das Bereitstellen des Speichers für main nicht vergessen.

    Gruß,

    Simon2.



  • Lumio schrieb:

    ...Das erinnert mich an Klassen (hab ich in C++ noch nicht durchgenommen), wo es ja einen Destruktor gibt...

    Ohne Klassen (und damit ohne Destruktoren) gibt es keine sinnvolle Möglichkeit. RAII basiert ebenso auf Klassen wie Smartpointer...

    Ansonsten bleibt dir wirklich nur die Allokation des Speichers von der Stelle der Freigabe zu trennen (Etwas das man in C++ in der Regel nicht machen sollte).

    Klassen sollten bei C++ immer eines der Themen sein, die man recht früh zumindest grundlegend durchnehmen sollte. Und sei es nur soweit, das man ganz grob weiß wie diese funktionieren, und zumindest eine Hand voll nützlicher Klassen aus der Standardbibliothek verwenden kann (Aus meiner Sicht reichen erstmal die absoluten Grundlagen zu std::string, std::vector, std::cin sowie std::cout). Meist benötigt man bei einfachen Programmen dann noch kein (sichtbares) Speichermanagement.

    Leider lehren noch zuviele C++ Bücher, Lehrer und Dozenten erst mehr oder weniger C.


Anmelden zum Antworten