Resizable array class mit falscher Ausgabe


  • Gesperrt

    Könnt ihr bitte einmal schauen, die Ausgabe ist ganz seltsam:

    #include <iostream>
    
    template <typename T>
    class ResizeArray
    {
    private:
        T *tp;
        int size_a = 0;
        int size_b = 100;
        void checkResize()
        {
            if (size_a == size_b)
            {
                int size_c = size_b + (size_b << 1);
                T *ntp = new T[size_c];
                for (int i = 0; i < size_c; i++)
                {
                    if (i < size_a)
                        ntp[i] = tp[i];
                    else
                        ntp[i] = 0;
                }
                delete (tp);
                tp = ntp;
                size_b = size_c;
            }
            else if (size_b != 100 && size_a < (size_b << 1))
            {
                int size_c = (size_b / 3) >> 1;
                T *ntp = new T[size_c];
                for (int i = 0; i < size_c; i++)
                {
                    if (i < size_a)
                        ntp[i] = tp[i];
                    else
                        ntp[i] = 0;
                }
                delete (tp);
                tp = ntp;
                size_b = size_c;
            }
        }
    
    public:
        ResizeArray()
        {
            tp = new T[size_b];
            for (int i = 0; i < size_b; i++)
            {
                tp[i] = 0;
            }
        }
        bool addLast(T t)
        {
            tp[size_a++] = t;
            checkResize();
            return true;
        }
        T removeLast()
        {
            if (size_a == 0)
                return 0;
            size_a--;
            T t = tp[size_a];
            tp[size_a] = 0;
            checkResize();
            return t;
        }
    };
    
    int main()
    {
        ResizeArray<int> ra;
        for (int i = 0; i < 3000; i++)
        {
            ra.addLast(i);
        }
        int i;
        do
        {
            i = ra.removeLast();
            std::cout << i << ", ";
            if (i % 10 == 0)
                std::cout << "\n";
        } while (i != 0);
        return 0;
    }
    
    ...
    119, 118, 117, 116, 115, 114, 113, 112, 111, 110, 
    109, 108, 107, 106, 105, 104, 103, 102, 101, 0, 
    


  • @EinNutzer0
    Lösung: std::vector


  • Gesperrt

    @DocShoe sagte in Resizable array class mit falscher Ausgabe:

    @EinNutzer0
    Lösung: std::vector

    Aber das erklärt nicht, weswegen er von 101 auf 0 springt. 😞


  • Gesperrt

    Sorry, hatte einen Denkfehler (und << mit >> vertauscht), die Größe sollte sich der Einfachheit halber immer verdoppeln oder halbieren:

    #include <iostream>
    
    template <typename T>
    class ResizeArray
    {
    private:
        T *tp;
        int size_a = 0;
        int size_b = 100;
        void checkResize()
        {
            if (size_a == size_b)
            {
                int size_c = size_b << 1;
                std::cout << "a " << size_c << "\n";
                T *ntp = new T[size_c];
                for (int i = 0; i < size_c; i++)
                {
                    if (i < size_a)
                        ntp[i] = tp[i];
                    else
                        ntp[i] = 0;
                }
                delete (tp);
                tp = ntp;
                size_b = size_c;
            }
            else if (size_b != 100 && size_a < (size_b >> 2))
            {
                int size_c = size_b >> 1;
                std::cout << "b " << size_c << "\n";
                T *ntp = new T[size_c];
                for (int i = 0; i < size_c; i++)
                {
                    if (i < size_a)
                        ntp[i] = tp[i];
                    else
                        ntp[i] = 0;
                }
                delete (tp);
                tp = ntp;
                size_b = size_c;
            }
        }
    
    public:
        ResizeArray()
        {
            tp = new T[size_b];
            for (int i = 0; i < size_b; i++)
            {
                tp[i] = 0;
            }
        }
        bool addLast(T t)
        {
            tp[size_a++] = t;
            checkResize();
            return true;
        }
        T removeLast()
        {
            if (size_a == 0)
                return 0;
            size_a--;
            T t = tp[size_a];
            tp[size_a] = 0;
            checkResize();
            return t;
        }
    };
    
    
    int main()
    {
        ResizeArray<int> ra;
        for (int i = 0; i < 3000; i++)
        {
            ra.addLast(i);
        }
        int i;
        do
        {
            i = ra.removeLast();
            std::cout << i << ", ";
            if (i % 10 == 0)
                std::cout << "\n";
        } while (i != 0);
        return 0;
    }
    


  • @EinNutzer0 sagte in Resizable array class mit falscher Ausgabe:

    ...
    

    wtf.

    @EinNutzer0 sagte in Resizable array class mit falscher Ausgabe:

    die Größe sollte sich der Einfachheit halber immer verdoppeln oder halbieren

    Dann schreib' doch halt auch *= 2 und /= 2.



  • WARNING: Visual Leak Detector detected memory leaks!
    ---------- Block 11 at 0x000000005D2AF160: 400 bytes ----------
      Leak Hash: 0xB6414058, Count: 1, Total 400 bytes
      Call Stack (TID 17336):
        ucrtbased.dll!malloc()
        codefun.exe!0x00007FF692BE39E3()
        codefun.exe!0x00007FF692BE2F43()
        codefun.exe!0x00007FF692BE2944()
        codefun.exe!0x00007FF692BE2D10()
        codefun.exe!0x00007FF692BE2DE3()
        codefun.exe!0x00007FF692BE38F9()
        codefun.exe!0x00007FF692BE379E()
        codefun.exe!0x00007FF692BE365E()
        codefun.exe!0x00007FF692BE3989()
        KERNEL32.DLL!BaseThreadInitThunk() + 0x1E bytes
        ntdll.dll!RtlUserThreadStart() + 0x2B bytes
      Data:
        00 00 00 00    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
        00 00 00 00    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
        00 00 00 00    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
        00 00 00 00    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
        00 00 00 00    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
        00 00 00 00    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
        00 00 00 00    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
        00 00 00 00    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
        00 00 00 00    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
        00 00 00 00    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
        00 00 00 00    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
        00 00 00 00    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
        00 00 00 00    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
        00 00 00 00    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
        00 00 00 00    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
        00 00 00 00    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
    
    
    Visual Leak Detector detected 1 memory leak (452 bytes).
    Largest number used: 19304 bytes.
    Total allocations: 38172 bytes.
    Visual Leak Detector is now exiting.
    

    Zumindest brauch' ich so den Code nicht lesen.

    // ach so. Destruktor wär' ein Hit. Und dann noch die anderen viereinhalb bis 5.


  • Mod

    @Swordfish sagte in Resizable array class mit falscher Ausgabe:

    // ach so. Destruktor wär' ein Hit. Und dann noch die anderen viereinhalb bis 5.

    Jetzt bin ich neugierig: Welchen zählst du nur halb?



  • @SeppJ The Rule of The Big Four (and a half) – Move Semantics and Resource Management
    swap()

    Vielleicht kann man auch noch size_e bis size_k einbauen. *scnr*


  • Gesperrt

    So jetzt:

    #include <iostream>
    #include <string>
    
    template <typename T>
    class ResizeArray
    {
    private:
        T *tp;
        int size_a = 0;
        int size_b = 100;
        void checkResize()
        {
            if (size_a == size_b)
            {
                int size_c = size_b << 1;
                std::cout << "a " << size_c << "\n";
                checkResize(size_c);
            }
            else if (size_b != 100 && size_a < (size_b >> 2))
            {
                int size_c = size_b >> 1;
                std::cout << "b " << size_c << "\n";
                checkResize(size_c);
            }
        }
        void checkResize(int size_c)
        {
            T *ntp = new T[size_c];
            for (int i = 0; i < size_c; i++)
            {
                if (i < size_a)
                    ntp[i] = tp[i];
                // else
                // ntp[i] = 0;
            }
            delete[] tp;
            tp = ntp;
            size_b = size_c;
        }
    
    public:
        ResizeArray()
        {
            tp = new T[size_b];
        }
        ~ResizeArray()
        {
            delete[] tp;
        }
        bool isEmpty()
        {
            return size_a == 0;
        }
        bool addLast(T t)
        {
            tp[size_a] = t;
            size_a++;
            checkResize();
            return true;
        }
        T removeLast()
        {
            if (isEmpty())
                return 0;
            size_a--;
            T t = tp[size_a];
            checkResize();
            return t;
        }
    };
    
    int main()
    {
        ResizeArray<std::string> ra;
        for (int i = 0; i < 3000; i++)
        {
            ra.addLast(std::to_string(i));
        }
        while (!ra.isEmpty())
        {
            std::cout << ra.removeLast() << ", ";
        }
        return 0;
    }
    

    @Swordfish sagte in Resizable array class mit falscher Ausgabe:

    Dann schreib' doch halt auch *= 2 und /= 2.

    Das Problem is halt, dass *= und /= sehr teure Operationen sind und << und >> sehr billige Operationen sind.

    Wir sind hier zwar nicht bei SO, aber wenn man sich unsicher ist und eine Antwort nicht genau weiß, wäre es vielleicht besser, sich etwas "zurückzunehmen".
    😃



  • @EinNutzer0 sagte in Resizable array class mit falscher Ausgabe:

    Das Problem is halt, dass *= und /= sehr teure Operationen sind und << und >> sehr billige Operationen sind.

    Träum weiter


  • Gesperrt

    @manni66 sagte in Resizable array class mit falscher Ausgabe:

    @EinNutzer0 sagte in Resizable array class mit falscher Ausgabe:

    Das Problem is halt, dass *= und /= sehr teure Operationen sind und << und >> sehr billige Operationen sind.

    Träum weiter

    Provoziere weiter 🙄



  • @EinNutzer0 Du stehst es dir doch so auf Assembler? Schau dir den Output von einem Bitshift um 1 und mul/div 2 von deinem Lieblingscompiler an. Und dann komm zurück und entschuldige Dich bei @manni66. 👍

    Subtext: Für wie dämlich hältst du Compiler? Code wird von Menschen gelesen also schreibt man ihn auch für Menschen schmerz- und möglichst fehlerfrei lesbar. Aber du weißt sowieso alles besser obwohl du von tuten und blasen keine Ahnung hast.

    @Swordfish sagte in Implementieren einer eigenen Vektorklasse:

    Diskussion über das Grundgerüst eines Vectors ab da: https://www.c-plusplus.net/forum/topic/351034/run-time-check-failure-2/40

    Ich denke da kannst du nachlesen, was es alles für einen "richtigen" Vektor braucht.



  • @EinNutzer0 sagte in Resizable array class mit falscher Ausgabe:

    So jetzt:

    Lol. Ein Pseudovektording das per default 100 Ts konstruiert bloß weil man es instanziiert. Ich hau' mich weg.
    Rule of Five immer noch nicht angekratzt obwohl man es dir unter die Nase gerieben hat.


  • Gesperrt

    @Swordfish sagte in Resizable array class mit falscher Ausgabe:

    @EinNutzer0 sagte in Resizable array class mit falscher Ausgabe:

    So jetzt:

    Lol. Ein Pseudovektording das per default 100 Ts konstruiert bloß weil man es instanziiert. Ich hau' mich weg.

    Naja, wenn man ein ResizeArray instanziiert, dann möchte man es idR auch verwenden...

    @manni66 Sorry, hoffe habe dich nicht verletzt. 😞

    @ all : Was ist denn noch "nicht richtig"?

    @Swordfish : Bevor das in Streit und Pöbeleien ausartet, setz dich ein paar Minuten auf die Hände. 😉



  • @EinNutzer0 sagte in Resizable array class mit falscher Ausgabe:

    Naja, wenn man ein ResizeArray instanziiert, dann möchte man es idR auch verwenden...

    Wenn ich einen dynamischen Container für Ts haben will will ich nicht automatisch 100 Ts. Das hat nichts mit Pöbelei zu tun. Du machst schlicht Unfug weil du es nicht besser weißt. Und wenn dann Leute um die Ecke kommen die dir sagen daß es Unfug ist dann kommst du mit irgendeinem anderen Unfug daher und glaubst das Gegenüber hätte keine Ahnung. Geh' mal davon aus daß die "Regulars" hier im Forum alle massiv mehr Ahnung haben als du. Besorg' dir ein Lehrbuch und fang' an C++ zu lernen. Nicht rumspielen. Lernen. Von einer vertrauenswürdigen Quelle wie zB. "Der C++ Programmierer" oder "C++ Primer".


  • Gesperrt

    @Swordfish sagte in Resizable array class mit falscher Ausgabe:

    will ich nicht automatisch 100 Ts.

    Leider nein, leider gar nicht. 😉


  • Mod

    @EinNutzer0 sagte in Resizable array class mit falscher Ausgabe:

    @ all : Was ist denn noch "nicht richtig"?

    Halt die ganzen Grundlagen, wie man in C++ überhaupt ressourcenhaltende Objekte baut, sind komplett falsch. Wenn der einzige Sinn deiner Klasse das Halten einer Ressource ist, ist das schon ein ziemlich gravierender Mangel. Da du aber keinen Schimmer zu haben scheinst, wovon ich und Swordfish reden, obwohl alle wichtigen Stichworte schon mehrmals genannt wurden, hast du dir offensichtlich nicht einmal die Grundlagen zu dem Thema angeeignet. Oder tust dumm. In beiden Fällen ist es nutzlos, darauf genauer einzugehen. Falls du ernsthaft nicht weißt, wovon wir hier reden, dann findest du zur Ressourcenverwaltung in C++ überall Erklärungen. Die Ressourcenverwaltung in C++ ist nämlich relativ eigen, quasi ein herausragendes Merkmal des Sprachdesigns, und so wichtig, dass es sogar spezielle Namen dafür gibt.

    (Das machen sonst nur Rust und ein paar Exoten auch so, oder fällt jemandem eine andere weit verbreitete Sprache mit den gleichen Konzepten ein?)


  • Gesperrt

    @SeppJ Das ist relativ plumpes Drum-herum-Reden um den heißen Brei und überdies noch beleidigend.

    Was ist denn gegenüber std::vector falsch? Ich hoffe, nicht nur große Klappe mit wenig dahinter...



  • @EinNutzer0 sagte in Resizable array class mit falscher Ausgabe:

    Was ist denn gegenüber std::vector falsch?

    Alles. Auf diesem fachlichen Niveau über so eine Thematik auch nur ansatzweise zu diskutieren hat keinen Sinn.

    @Swordfish sagte in Implementieren einer eigenen Vektorklasse:

    Diskussion über das Grundgerüst eines Vectors ab da: https://www.c-plusplus.net/forum/topic/351034/run-time-check-failure-2/40

    Ich denke da kannst du nachlesen, was es alles für einen "richtigen" Vektor braucht.

    Aber den Link habe ich dir ja schon weiter oben gegeben.



  • @EinNutzer0 sagte in Resizable array class mit falscher Ausgabe:

    Was ist denn gegenüber std::vector falsch?

    Steht doch schon explizit dran, x-mal. Ich fand den Ton hier dir gegenüber erst auch etwas überzogen, aber mittlerweile versteh ich dich auch echt nicht mehr.


Anmelden zum Antworten