operator new zerstört Speicherstruktur



  • Wenn ich mit new Speicher anfordere und mit delete wieder frei gebe, dann stürzt mein Programm ab, wenn ich es zusammen mit dem Debugger laufen lasse. Ersetze ich new und delete durch gleichwertige Konstruktionen aus malloc und free, dann funktioniert es immer. Heisst das, dass in der Implementation der Standard-Bibliothek ein Fehler ist, oder kann man dieses Verhalten auf ein Problem in meinem Sourcecode zurückführen? Das Programm sieht, auf den Fehler reduziert etwa so aus:

    template<typename T>
    struct Foo
    {
        Foo()
        {
            this->Bar = new T[0xff];
        }
        ~Foo()
        {
            delete(this->Bar);
        }
        static Foo *GetFoo()
        {
            static Foo Obj;
            return &Obj;
        }
    private:
        T *Bar;
    };
    int main()
    {
        Foo<unsigned> *MyFoo = Foo<unsigned>::GetFoo();
        return 0;
    }
    

    Der Fehler tritt in der Funktion ~Foo auf, die, wie es der Standard fordert nach dem Verlassen von main aufgerufen wird.



  • Achtung: Ich benutze natürlich delete[] this->Bar und nicht delete(this->Bar)!



  • delete [] ...
    

    😃

    Edit: Habe deinen Beitrag zu spät gesehen...



  • static Foo Obj;
    

    Das gefällt mir irgendwie nicht. Foo ist doch eine Template Klasse und du benutzt es da wie eine normale...

    Vielleicht hilft ja das :

    static Foo<T> Obj;
    

    Was besseres fällt mir jetzt auch nicht ein :xmas1:



  • Joa, ist schon klar. Habe ich auch so im richtigen Code 💡 . Natürlich habe ich es dann falsch abgeschrieben... genau wie mit dem operator delete vorhin.



  • Konntest du mit deinem Beispiel oben den Fehler reproduzieren?



  • User--- schrieb:

    Konntest du mit deinem Beispiel oben den Fehler reproduzieren?

    Ja.



  • Ich nicht 😮 , bei mir kompiliert und läuft das anstandslos (sagt auch gdb)!



  • Das ist nicht gut! Ich muss darüber nachdenken, wie ich das Problem umgehen kann. Vielleicht sollte ich meine eigenen Operatoren schreiben, die malloc und free benutzen und diese via Makro einbinden...



  • Ist T bei dir ein polymorpher Typ oder hast du wirklich immer nur einen Typ in dem Array?



  • An schrieb:

    Ist T bei dir ein polymorpher Typ oder hast du wirklich immer nur einen Typ in dem Array?

    Es sollte im Prinzip immer funktionieren, egal was T nun ist.



  • WTF?! schrieb:

    An schrieb:

    Ist T bei dir ein polymorpher Typ oder hast du wirklich immer nur einen Typ in dem Array?

    Es sollte im Prinzip immer funktionieren, egal was T nun ist.

    Du kannst in nem statischen Array keine polymorphen Typen speichern, da delete[] von dem statischen Typ (also der gemeinsamen Basis) ausgeht und wenn die Typen sich in ihrer Größe unterscheiden hast du nen Problem.
    Warum kannst du nicht einach nen boost::array oder std::vector verwenden?



  • An seinem Code ist nichts falsch, und es ist völlig egal, welcher Typ T ist. Er scheint nur eine ziemlich kaputte C++-Implementation zu haben



  • An schrieb:

    WTF?! schrieb:

    An schrieb:

    Ist T bei dir ein polymorpher Typ oder hast du wirklich immer nur einen Typ in dem Array?

    Es sollte im Prinzip immer funktionieren, egal was T nun ist.

    Du kannst in nem statischen Array keine polymorphen Typen speichern, da delete[] von dem statischen Typ (also der gemeinsamen Basis) ausgeht und wenn die Typen sich in ihrer Größe unterscheiden hast du nen Problem.
    Warum kannst du nicht einach nen boost::array oder std::vector verwenden?

    Inwiefern sollte ein Vektor oder ein Wrapper um das Array etwas am Verhalten ändern? Vor allem, da std::vector prinzipiell auch nur ein dynamisches Array ist, es muss ein zusammenhängender Speicherblock sein! Außerdem hat er in seinem Beispiel T=unsigned gesetzt, nicht gerade ein für seine Polymorphie bekannter Typ!
    Also mein Compiler (mingw g++ 3.4.4) kriegt das hin. Welchen benutzt du?



  • Freak_Coder schrieb:

    static Foo Obj;
    

    Das gefällt mir irgendwie nicht. Foo ist doch eine Template Klasse und du benutzt es da wie eine normale...

    Was aber vollkommen legitim ist, denn Foo ist innerhalb der Klasse implizit Foo<T>.



  • groovemaster schrieb:

    denn Foo ist innerhalb der Klasse implizit Foo<T>.

    Achso, thx.
    Dachte immer das nur die Elementfunktionen implizit Templates sind.


Anmelden zum Antworten