Zeiger = 0;



  • dot schrieb:

    Ich hab eine kleine Aufgabe für dich:

    void foo()
    {
      int* x = new int;
    
      if (hell_yeah())
        goto get_santa;
    
      // ...
    
    a:
    
      if (bla)
        return;
    
      if (solo)
        throw std::runtime_error("i have a bad feeling about this");
    
      // ...
    
      return;
    
    get_santa:
    
      if (hohoho())
      {
        x = new int(42);
        goto a;
      }
    
    }
    

    Füge in diese Funktion alle deletes ein, die notwendig sind, damit der int, auf den x zeigt, immer und unter allen Umständen freigegeben wird.

    void foo()
    {
      int* x = new int;
    
      if (hell_yeah())
        goto get_santa;
    
      // ...
    
    a:
    
      delete x;///Erstes
    
      if (bla)
        return;
    
      if (solo)
        throw std::runtime_error("i have a bad feeling about this");
    
      // ...
    
      return;
    
    get_santa:
    
      if (hohoho())
      {
        delete x;///Drittes
        x = new int(42);
        goto a;
      }
    
      delete x;///Zweites
    
    }
    

    Dot, so richtig?

    @Kellerautomat: SCNR 😃 jetzt aber. Versprochen.



  • Ne, geh nochmal alle Pfade durch.

    Edit: Um genau zu sein, fehlen dir fast alle Pfade.



  • Michael E. schrieb:

    Ne, geh nochmal alle Pfade durch.

    Jetzt aber 😃



  • Immer noch viiiel zu wenig.



  • Außerdem mach delete a; keinen Sinn. Und dein erstes delete ist falsch. Wenn das goto nicht genommen wurde, löscht du dort den int, der später aber gebraucht wird.



  • @Dot: Editiert. d elete x; . Da denk ich gleich drüber nach... ⚠



  • void foo()
    {
          int* x = new int;
    
          if (hell_yeah())
                goto get_santa;
    
          // ...
    
    a:
    
          if (bla)
          {
                delete x;
                return;
          }
    
          if (solo)
          {
                delete x;
                throw std::runtime_error("i have a bad feeling about this");
          }
    
          // ...
    
          delete x;
          return;
    
    get_santa:
    
          if (hohoho())
          {
                delete x;
                x = new int(42);
                goto a;
          }
    
          delete x;
    }
    

    Jetzt?
    Ich wusste nicht, dass bei den ///.... noch der Pointee gebraucht wird 😉



  • Sieht besser aus. Die Frage war aber eigentlich an den Threadersteller gerichtet, in der Hoffnung dass ihm vielleicht klar wird, wieso er in freier Wildbahn nicht mit new und delete herumwerfen sollte...



  • dot schrieb:

    Sieht besser aus. Die Frage war aber eigentlich an den Threadersteller gerichtet, in der Hoffnung dass ihm vielleicht klar wird, wieso er in freier Wildbahn nicht mit new und delete herumwerfen sollte...

    Hört auf mit C++ zu programmieren, eh wollte ich nicht greade irgendetwas Pro C++ los werden o.O?



  • Hacker: Immer noch längst nicht. Vielleicht sollte man dir sagen, dass die Aufgabe nicht lösbar ist. Findest du heraus, warum das so ist?



  • void a(int* x)
    {
      if (bla)
        return;
    
      if (solo)
        throw std::runtime_error("i have a bad feeling about this");
    }
    
    void get_santa(int* x)
    {
      if (hohoho())
      {
        int* tmp = new int(42);
        delete x;
        x = tmp;
        a(x);
      }
    }
    
    void foo()
    {
      int* x = new int;
    
      try
      {
        if (hell_yeah())
          get_santa(x);
      }
    
      catch(...)
      {
        delete x;
        throw;
      }
    }
    


  • Michael E. schrieb:

    Hacker: Immer noch längst nicht. Vielleicht sollte man dir sagen, dass die Aufgabe nicht lösbar ist. Findest du heraus, warum das so ist?

    Nein, ich schäme mich. Vielleicht, weil sie lächerlicher Spaghetticode ist?
    Ich hab jetzt nicht lange dran gesessen... aber ich glaube alles ist so Ok...?
    @Kellerautomat: Wieso Pufferst du da? Du brauchst doch tmp gar nicht.



  • Kellerautomat: Dein Code tut nicht mal mehr dasselbe. Ganz davon abgesehen, dass dein Code nicht Exception-safe ist.



  • Hacker schrieb:

    Nein, ich schäme mich. Vielleicht, weil sie lächerlicher Spaghetticode ist?
    Ich hab jetzt nicht lange dran gesessen... aber ich glaube alles ist so Ok...?

    Wenn du dich bemühst, werde ich dir weitere Hilfestellungen geben. Wenn du allerdings zu faul dafür bist, sehe ich nicht ein, warum ich einen Roman dazu schreiben sollte. Kellerautomat sollte dir zumindest weitere Anregungen gegeben haben.



  • Man sollte vielleicht darauf hinweisen, dass in den // ... natürlich nicht nur x gültig sein muss, sondern dass dort potentiell auch Exceptions fliegen können...



  • dot schrieb:

    Man sollte vielleicht darauf hinweisen, dass dort wo //... natürlich nicht nur x gültig sein muss, sondern dass dort potentiell auch Exceptions fliegen können...

    Jajaja. Das ist mir auch gerade in den Sinn gekommen. Nicht nur bei Funktionen wie hohoho() oder hell_yeah() ...

    Dann fängt man die Exceptions aber einfach, oder? Und gibt den Speicher von x frei?



  • Bezüglich der Antwort:

    Aber das ist doch keine Schuld des Operators?! Es ist das Problem des Programmierers ob er Fehler macht oder nicht, das hättet ihr zu aller Anfang auch sagen müssen, ich weiß was ich tue, hatte nur ein wenig theoretische Hilfe bezüglich der Funktionalität eines Zeigers und deren Benutzung gebraucht...

    1. Wenn man den Code richtig schreibt wird das Programm auch ohne Fehler funktionieren.
    2. Mein Ziel ist es nicht möglichst viel Zeit zu sparen nach dem Motto: "Hauptsache es läuft richtig", mein Ziel ist schon von Anfang an die Low-Level Programmierung gewesen.
    3. Befolge ich lieber die Regel, goto erst gar nicht zu nutzen!

    class Data;
    
    class Pointer
    { 
    private:
    
        Data* data;
    
    public:
    
        Pointer(Data& d)
        {
            data = new Data(d);
        }
    
        ~Pointer()
        {
            delete data;
            data = 0;
        }
    }; 
    
    int main(void)
    {
        Data d;
        Pointer* p = new Pointer(d);
    
        delete p;
        p = 0;
    
        return 0;
    }
    

    Aaaaaalso, noch mal Schritt für Schritt:

    1 >> Eine Instanz namens 'd' der Klasse Data wird angelegt.

    2 >> Ein Zeiger namens 'p' der Klasse Pointer wird angelegt. Status: 'p' zeigt ins Nichts.
    2.1 >> Operator new ruft den Konstruktor der Klasse Pointer auf und erzeugt 1 neues Objekt der Klasse Pointer in 'p'. Status: 'p' zeigt auf Speicheradresse des neuen Objekts.
    2.2 >> 'd' Wird als Konstruktorparameter übergeben.
    2.3 >> auf den Zeiger Pointer::data wird per Operator new 1 Objekt der Klasse Data angelegt welches per Kopierkonstruktor mit 'd' initialisiert wird. Status: 'data' zeigt auf Speicheradresse des neuen Objekts.

    3 >> Operator delete ruft den Destruktor des Objekts in 'p' auf
    3.1 >> über delete wird der Destruktor des Objekts, welcher sich in Pointer::data befindet, aufgerufen, das Objekt in 'data' wird gelöscht. Status: 'data' zeigt auf Speicheradresse des gelöschten Objekts.
    3.2 >> Pointer::data wird auf 0 Gesetzt (was in diesem Beispiel aber nicht wirklich nötig ist) da sich auf dessen Adresse Nichts mehr befindet. Status: 'data' zeigt ins Nichts.

    4 >> Zeiger 'p' wird auf 0 gesetzt da sich auf dessen Adresse Nichts mehr befindet Status: 'p' zeigt ins Nichts.

    5 >> Maximale Reichweite von 'p' wird erreicht
    4.1 >> Destruktor von 'p' wird aufgerufen, das Objekt wird gelöscht.

    6 >> Das Programm wird beendet, 0 wird an das Betriebssystem zurückgeben.

    P.S. Gratuliere alle zum Sieg :schland:



  • 1. Wenn man den Code richtig schreibt wird das Programm auch ohne Fehler funktionieren.
    2. Mein Ziel ist es nicht möglichst viel Zeit zu sparen nach dem Motto: "Hauptsache es läuft richtig", mein Ziel ist schon von Anfang an die Low-Level Programmierung gewesen.
    3. Befolge ich lieber die Regel, goto erst gar nicht zu nutzen!

    1. Nullaussage
    2. Low-Level? Glaub mir, die willst du nicht machen.
    3. Jau.

    RussianTux schrieb:

    Aaaaaalso, noch mal Schritt für Schritt:

    1 >> Eine Instanz namens 'd' der Klasse Data wird angelegt.

    2 >> Ein Zeiger namens 'p' der Klasse Pointer wird angelegt. Status: 'p' zeigt ins Nichts.
    2.1 >> Operator new ruft den Konstruktor der Klasse Pointer auf und erzeugt 1 neues Objekt der Klasse Pointer in 'p'. Status: 'p' zeigt auf Speicheradresse des neuen Objekts.
    2.2 >> 'd' Wird als Konstruktorparameter übergeben.
    2.3 >> auf den Zeiger Pointer::data wird per Operator new 1 Objekt der Klasse Data angelegt welches per Kopierkonstruktor mit 'd' initialisiert wird. Status: 'data' zeigt auf Speicheradresse des neuen Objekts.

    3 >> Operator delete ruft den Destruktor des Objekts in 'p' auf
    3.1 >> über delete wird der Destruktor des Objekts, welcher sich in Pointer::data befindet, aufgerufen, das Objekt in 'data' wird gelöscht. Status: 'data' zeigt auf Speicheradresse des gelöschten Objekts.
    3.2 >> Pointer::data wird auf 0 Gesetzt (was in diesem Beispiel aber nicht wirklich nötig ist) da sich auf dessen Adresse Nichts mehr befindet. Status: 'data' zeigt ins Nichts.

    4 >> Zeiger 'p' wird auf 0 gesetzt da sich auf dessen Adresse Nichts mehr befindet Status: 'p' zeigt ins Nichts.

    5 >> Maximale Reichweite von 'p' wird erreicht
    4.1 >> Destruktor von 'p' wird aufgerufen, das Objekt wird gelöscht.

    6 >> Das Programm wird beendet, 0 wird an das Betriebssystem zurückgeben.

    P.S. Gratuliere alle zum Sieg :schland:

    So ganz grob alles richtig. Reihenfolge manchmal falsch, 5. verstehe ich nicht, meinst du etwa das der Scope verlassen wird?- sonst...

    Zeiger zeigen übrigens nicht einfach ins Nichts.



  • Hacker schrieb:

    1. Wenn man den Code richtig schreibt wird das Programm auch ohne Fehler funktionieren.
    2. Mein Ziel ist es nicht möglichst viel Zeit zu sparen nach dem Motto: "Hauptsache es läuft richtig", mein Ziel ist schon von Anfang an die Low-Level Programmierung gewesen.
    3. Befolge ich lieber die Regel, goto erst gar nicht zu nutzen!

    1. Nullaussage
    2. Low-Level? Glaub mir, die willst du nicht machen.
    3. Jau.

    1. Also funktioniert das Programm ohne Fehler selbst wenn der Programmierer falsch programmiert? x))
    2. Vielleicht will ich damit ja anfangen? Weiß doch keiner so genau was ich möchte 🙂
    3 Jo.

    [quote="Hacker"]

    RussianTux schrieb:

    Aaaaaalso, noch mal Schritt für Schritt:

    1 >> Eine Instanz namens 'd' der Klasse Data wird angelegt.

    2 >> Ein Zeiger namens 'p' der Klasse Pointer wird angelegt. Status: 'p' zeigt ins Nichts.
    2.1 >> Operator new ruft den Konstruktor der Klasse Pointer auf und erzeugt 1 neues Objekt der Klasse Pointer in 'p'. Status: 'p' zeigt auf Speicheradresse des neuen Objekts.
    2.2 >> 'd' Wird als Konstruktorparameter übergeben.
    2.3 >> auf den Zeiger Pointer::data wird per Operator new 1 Objekt der Klasse Data angelegt welches per Kopierkonstruktor mit 'd' initialisiert wird. Status: 'data' zeigt auf Speicheradresse des neuen Objekts.

    3 >> Operator delete ruft den Destruktor des Objekts in 'p' auf
    3.1 >> über delete wird der Destruktor des Objekts, welcher sich in Pointer::data befindet, aufgerufen, das Objekt in 'data' wird gelöscht. Status: 'data' zeigt auf Speicheradresse des gelöschten Objekts.
    3.2 >> Pointer::data wird auf 0 Gesetzt (was in diesem Beispiel aber nicht wirklich nötig ist) da sich auf dessen Adresse Nichts mehr befindet. Status: 'data' zeigt ins Nichts.

    4 >> Zeiger 'p' wird auf 0 gesetzt da sich auf dessen Adresse Nichts mehr befindet Status: 'p' zeigt ins Nichts.

    5 >> Maximale Reichweite von 'p' wird erreicht
    4.1 >> Destruktor von 'p' wird aufgerufen, das Objekt wird gelöscht.

    6 >> Das Programm wird beendet, 0 wird an das Betriebssystem zurückgeben.

    P.S. Gratuliere alle zum Sieg :schland:

    So ganz grob alles richtig. Reihenfolge manchmal falsch, 5. verstehe ich nicht, meinst du etwa das der Scope verlassen wird?- sonst...

    Genau das habe ich damit gemeint, die "Reichweite" eines Objekts ist ja auch eigentlich die Länge des Anweisungsblocks.

    Hacker schrieb:

    Zeiger zeigen übrigens nicht einfach ins Nichts.

    Jo das ist klar, soll einfach die 0 symbolisieren, denn theoretisch zeigt der Zeiger ja auch "ins Leere" wenn er == 0 ist, oder versteh ich das irgendwie falsch?



  • Hacker schrieb:

    @Kellerautomat: Wieso Pufferst du da? Du brauchst doch tmp gar nicht.

    Weißt du überhaupt, was puffern ist? 🙄
    Ohne scheiß, hör mal auf zu posten. Deine restlichen Posts sind auch voller Humbug.

    Und um deine falsch gestellt Frage zu beantworten: Exception-Safety. Stichwort: Starke Garantie.

    Michael E. schrieb:

    Kellerautomat: Dein Code tut nicht mal mehr dasselbe.

    Hab ich irgendwo was falsch kopiert? Hab darauf jetzt nicht geachtet. 🤡

    Michael E. schrieb:

    Ganz davon abgesehen, dass dein Code nicht Exception-safe ist.

    Wo denn?


Anmelden zum Antworten