realloc C++



  • @unskilled sagte in realloc C++:

    die (vermutlich gar nicht so dumme) alternative wäre wohl nen eigener allocator, der einfach (fast) alles am reserviert und selbst was realloc-mäßiges anbietet. das sieht aber recht schnell recht hässlich im quellcode aus (alloc überall rumreichen). Und hat wieder nen overhead. Wäre aber vom Lerneffekt und den Möglichkeiten her sicher am coolsten.

    Mit dem Overhead bin ich mir nicht so sicher, schliesslich unterstützt auch std::vector einen nutzerdefinierten Allocator. Dieser sollte eigentlich, sofern kein polymorphic_allocator verwendet wird, lediglich über den Allocator-Typ gegeben sein, der Teil des vector-Typs ist, also keinen zuzätzlichen Daten-Member benötigen. Auch würde ich davon ausgehen, dass zumindest der Standard-Allocator so leichtgewichtig implementiert ist, dass die Allokationen unter Compiler-Optimierungen zu direkten malloc/free-Aufrufen mit der richtigen Anzahl von Bytes zerfallen (obwohl ich mir das noch nicht direkt im Maschinencode angesehen habe).

    Ein eigener Allocator kann aber relativ schnell ziemlich komplex werden, daher ein anderer Vorschlag:

    Wie wäre es, wenn dein Vector zur Compile-Zeit erkennt, ob eine malloc-Implementation verwendet wird, die ein flexibleres reallocunterstützt. Du kannst den speziellen reallocate-Code dann für ausgewählte Implementationen unterstützen, z.B. indem du in diesem Fall dann auf realloc2 von nedmalloc oder auf _expand von Visual C++ (https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/expand?view=vs-2017) zurückgreifst. Für unterstütze Allokatoren kannst du dann einen effizienteren Code anbieten.

    @Finnegan

    Welchen Vorteil hat C, wenn man C++ kann und ein C++-Compiler für die Zielplattform verfügbar ist?

    Na der Vorteil liegt auf der Hand: Ich wüsste zweifelsohne, dass memmove wohl definiert ist (in C ist es das auf struct foo von oben). Aber mir persönlich ist da RAII zu viel wert.

    Dieser scheinbare Vorteil trügt. In C++ ist memmove für exakt die selben Objekt-Kategorien (POD) wie in C "wohl definiert". In dieser Hinsicht kann C++ nicht "weniger" als C.

    Also zurück zur Frage:
    Ist memmove aus der C++ standard lib auf ein nicht-trivial-kopierbares objekt UB? (Das Problem an der Frage ist natürlich offensichtlich: Jeder kann erst mal ja! sagen, bis dann jemand kommt und sagt "Nein, schaut: ...")
    Oder ist nur UB, was danach herauskommt? (T(old_mem) != T(new_mem))
    Oder (und?) ist das beides "[praktisch] well formed"?
    Oder ist es immer well formed; abgesehen davon, dass das neue Objekt eben Invarianz hervorrufen kann?

    Das Problem mit dem UB ist, dass es wahrscheinlich funktioniert, wenn man Klassen manuell als memmove-sicher markiert (siehe auch Beitrag von wob), theoretisch darf aber Compiler deinen Code so verändern, als würde dieser UB-Fall nicht eintreten. Er darf z.B. die memmove-Aufrufe für solche Typen komplett herausoptimieren. Ohne eine eigene Speicherverwaltung, oder eine spezifische mit flexiblem realloc, wie eben nedmalloc oder andere, wirst du also wohl oder übel mit dem UB leben müssen. Sowas kann man durchaus machen, es gibt jede Menge Code der sich auf ein spezielles Verhalten des Compilers bei UB verlässt (und nicht immer unbeabsichtigt). Man muss sich halt immer bewusst sein, dass es eben nicht standardkonform ist und vom Wohlwollen des jeweiligen Compilers abhängt.

    Mit dem UB leben und es wie folly::fbvector zu machen ist also die andere, wesentlich schneller umzusetzende Lösung (vs. eigener/vorgegebener Allocator).



  • @john-0 sagte in realloc C++:

    Warum sollte man C verwenden wollen?

    gegenfrage: warum sollte man eine funktion verwenden wollen, die eigentlich nur deshalb teil von c++ ist, weil c++ vor vielen jahren mal sowas wie "c mit erweiterungen" war?

    Es gibt dazu auf youtube von den diversen C++ Meetings Vorträge zum Anschauen.

    es gibt auf youtube auch garantiert vorträge zum anschauen, warum persil besser wäscht als ariel.



  • @Wade1234 sagte in realloc C++:

    gegenfrage: warum sollte man eine funktion verwenden wollen, die eigentlich nur deshalb teil von c++ ist, weil c++ vor vielen jahren mal sowas wie "c mit erweiterungen" war?

    Weshalb muss man hier im Forum immer wieder sinnfreie Grundsatzdiskussionen führen, wenn man etwas machen will/muss, was nicht den üblichen Gepflogenheiten in C++ entspricht? Es gibt auch für diese Sonderfälle gute Gründe. Also, ist es sinnvoll C++ für Microcontroller zu verwenden – ja. Ist die gestellte Frage in diesem Kontext sinnvoll – ja. Weshalb also das viele Rauschen im Thread?



  • ja ihr macht das schon alle......



  • @Finnegan sagte in realloc C++:

    @unskilled sagte in realloc C++:

    die (vermutlich gar nicht so dumme) alternative wäre wohl nen eigener allocator, der einfach (fast) alles am reserviert und selbst was realloc-mäßiges anbietet. das sieht aber recht schnell recht hässlich im quellcode aus (alloc überall rumreichen). Und hat wieder nen overhead. Wäre aber vom Lerneffekt und den Möglichkeiten her sicher am coolsten.

    Mit dem Overhead bin ich mir nicht so sicher, schliesslich unterstützt auch std::vector einen nutzerdefinierten Allocator. Dieser sollte eigentlich, sofern kein polymorphic_allocator verwendet wird, lediglich über den Allocator-Typ gegeben sein, der Teil des vector-Typs ist, also keinen zuzätzlichen Daten-Member benötigen. Auch würde ich davon ausgehen, dass zumindest der Standard-Allocator so leichtgewichtig implementiert ist, dass die Allokationen unter Compiler-Optimierungen zu direkten malloc/free-Aufrufen mit der richtigen Anzahl von Bytes zerfallen (obwohl ich mir das noch nicht direkt im Maschinencode angesehen habe).

    Na nur einen Standard-Allok. zu schreiben, der free/malloc/realloc aufruft meinte ich nicht. So mache ich es ja jetzt und wollte eben ein sinnvolles kriterium für irgendetwas is_relocatable-mäßiges haben. Die Lösung vom fb-vektor finde ich verhältnismäßig hübsch und elegant.

    Ich hatte von ner eigenen speicherverwaltung im allokator geredet. ein memory-pool halt; kein allokator im eigentlichen sinne.

    Dieser scheinbare Vorteil trügt. In C++ ist memmove für exakt die selben Objekt-Kategorien (POD) wie in C "wohl definiert". In dieser Hinsicht kann C++ nicht "weniger" als C.

    Naja - in C hätte man das Problem nicht, weil es ja ein trivial zu kopierender Typ wäre und die funktionen zum manipulieren der Daten außerhalb sind und nicht so versteckt aufgerufen werden können.

    Das Problem mit dem UB ist, dass es wahrscheinlich funktioniert, wenn man Klassen manuell als memmove-sicher markiert (siehe auch Beitrag von wob), theoretisch darf aber Compiler deinen Code so verändern, als würde dieser UB-Fall nicht eintreten. Er darf z.B. die memmove-Aufrufe für solche Typen komplett herausoptimieren. Ohne eine eigene Speicherverwaltung, oder eine spezifische mit flexiblem realloc, wie eben nedmalloc oder andere, wirst du also wohl oder übel mit dem UB leben müssen. Sowas kann man durchaus machen, es gibt jede Menge Code der sich auf ein spezielles Verhalten des Compilers bei UB verlässt (und nicht immer unbeabsichtigt). Man muss sich halt immer bewusst sein, dass es eben nicht standardkonform ist und vom Wohlwollen des jeweiligen Compilers abhängt.

    Deshalb hatte ich noch den 2. Thread verlinkt und zitiert.

    Also unterm Strich und als Zusammenfassung:
    is_relocatable habe ich vom FBvector abgeguckt.
    Meine Container rufen ein allocator::reallocate auf und der ruft entweder ::realloc auf oder eben allocate std::uninitialized_copy* und deallocate.
    Damit habe ich UB, wenn der Klassen-Schreiber das für nötig hält (relocatable spezialisierung) und ansonsten ist's standard-konform.

    1*
    alternativ dazu etwas uninitialized_swap-mäßiges oder doch nur N x {placement_new + destroy}.
    Da hab ich mich noch nicht entschieden.


  • Gesperrt

    @john-0 sagte in realloc C++:

    Also, ist es sinnvoll C++ für Microcontroller zu verwenden – ja.

    Zumindest seit es Microcontroller gibt, die über mehrere MB RAM und Flash verfügen. Aber darauf nutzt man dann doch lieber VM-Sprachen, die einen GC, JIT-Compilierung und eine fette Laufzeitumgebung haben. 🐱



  • @RBS2 Merkst du eigentlich, daß du nervst ohne irgendwo was Sinnvolles beizutragen? Du brauchst nicht ständig breit vor dir hertragen, daß die einzig sinnvolle Sprache für alles C und nur C ist. Daß das deine Anschauung ist haben glaube ich inzwischen alle verstanden.


  • Gesperrt

    @Swordfish sagte in realloc C++:

    Du brauchst nicht ständig breit vor dir hertragen, daß die einzig sinnvolle Sprache für alles C und nur C ist.

    Und das, nachdem ich schrieb, dass das altbackene C++ oft und gern durch Sprachen der neuren Generation ersetzt wird. Du musst mich ja für den totalen Nostalgiker halten.



  • Und da wir hier im C++-Forum sind: Jason Turner hat auch mal mit C++ und Microcontrollern herumgespielt. Schon etwas her, aber vielleicht trotzdem interessant: https://www.youtube.com/watch?v=YJzIcmD7IsY (und folgende Episoden)



  • @RBS2 sagte in realloc C++:

    das altbackene C++

    Aha. C++20 ist altbacken, quasi das Brot von gestern. Muss ich mir merken.


Anmelden zum Antworten