realloc liefert zu viel speicher



  • malloc() und Co. arbeiten wunderbar - mit PoD-Typen. Aber sie haben keine Ahnung von Konstruktoren und dergleichen.

    (und intern dürfte realloc auch nicht viel anders machen als einen neuen Speicherblock abzufordern und die Daten dort reinzukopieren - nur eventuell auf HW-Ebene besser optimiert)



  • also in einen anderen Thread, wurde mir mal gesagt das realloc ersteinmal versucht den aktuellen speicher zu vergrößern und andernfalls neu allokiert. andere frage was sind denn PoD-Typen?



  • FreakyBKA schrieb:

    also in einen anderen Thread, wurde mir mal gesagt das realloc ersteinmal versucht den aktuellen speicher zu vergrößern und andernfalls neu allokiert.

    Korrekt. Und wenn man komplexe Speicheranforderung in C++ braucht, kann man Allokatoren verwenden.

    andere frage was sind denn PoD-Typen?

    Plain old data. Alles, was keine Klasse ist.



  • Naja, das kommt darauf an was man unter einer Klasse versteht...

    class Foo
    {
    public:
        int x;
        void sepp() { x++; }
    };
    

    -> Foo ist ein POD.
    Die genauen Regeln weiss ich aber auch nimmer, müsste ich selbst nachgucken.



  • hustbaer schrieb:

    Die genauen Regeln weiss ich aber auch nimmer, müsste ich selbst nachgucken.

    Kurzfassung: POD ist alles, was du auch als C-struct übergeben kannst. Ausführlicher: Keine Konstruktoren oder Destruktoren, keine Ableitung, keine virtuellen Methoden, keine privaten Elemente. (und natürlich müssen alle Member ebenfalls POD's oder built-in Typen sein)



  • Danke. z.B. bei Konstruktoren und non-public Members war ich mir nicht sicher -- würde ja eigentlich nicht stören.
    Andere Frage... ist das noch ein POD:

    class foo
    {
    public:
        int x;
    public:
        int y;
    };
    

    ?
    Weil ja x und y im Speicher nicht so hintereinander liegen müssen (kann auch erst y und dann x kommen) soweit ich den Standard kenne/verstehe.
    Geht das nun trotzdem noch als POD durch?



  • hustbaer schrieb:

    Danke. z.B. bei Konstruktoren und non-public Members war ich mir nicht sicher -- würde ja eigentlich nicht stören.

    Huh? Na gerade der Konstruktor macht doch einen riesigen Unterschied. Angenommen, man deklariert ein Feld von Objekten mit 1000 Einträgen. Wenn es sich um Non-PODs handelt, dann müssen 1000 Konstruktoren aufgerufen werden. Das kann für ganz erhebliche Performance-Unterschiede sorgen. Non-public-Members stören in der Tat nicht.


  • Mod

    hustbaer schrieb:

    Danke. z.B. bei Konstruktoren und non-public Members war ich mir nicht sicher -- würde ja eigentlich nicht stören.
    Andere Frage... ist das noch ein POD:

    class foo
    {
    public:
        int x;
    public:
        int y;
    };
    

    ?
    Weil ja x und y im Speicher nicht so hintereinander liegen müssen (kann auch erst y und dann x kommen) soweit ich den Standard kenne/verstehe.
    Geht das nun trotzdem noch als POD durch?

    Ist immer noch ein POD. Die Umordnungsregel trifft PODs nicht, denn man könnte immer einen layout-kompatiblen Typen konstruieren, der ohne zusätzliche Zugriffsspezifikation auskommt.

    Konstruktoren (&Destruktoren) sind im Prinzip der wichtigste Faktor, der zu nicht-PODs führt: ohne Konstruktor haben wir nur eine Anhäufung von Daten ohne inneren Zusammenhang - mithin auch keinerlei Invarianten, die während der Lebenszeit gelten könnten. Konstruktoren machen es erst möglich, dass aus einer bloßen Aggregation ein größeres Ganzes wird.



  • ZU dem Thema ne Frage, die mich schon länger beschäftigt: Warum gibt es kein C++-Equivalent zu realloc(). malloc() <-> new und free() <->delet ist ja klar, aber realloc()? Immerhin würde man doch vielleicht mal ein Feld vergrößern wollen.



  • geloescht schrieb:

    ZU dem Thema ne Frage, die mich schon länger beschäftigt: Warum gibt es kein C++-Equivalent zu realloc(). malloc() <-> new und free() <->delet ist ja klar, aber realloc()? Immerhin würde man doch vielleicht mal ein Feld vergrößern wollen.

    Weil C++ keine Abbildung von C mit neuen Worten ist. Für sich vergrößern wollende Felder gibt es so schöne Sachen wie std::vector<T>, die unter der Haube mit Allokatoren arbeiten die ähnliches wie realloc leisten dürften.



  • LordJaxom schrieb:

    Weil C++ keine Abbildung von C mit neuen Worten ist. Für sich vergrößern wollende Felder gibt es so schöne Sachen wie std::vector<T>, die unter der Haube mit Allokatoren arbeiten die ähnliches wie realloc leisten dürften.

    Der standardmäßig verwendete Allokator dürfte wohl auch bloß new und delete benutzen (ist bei mir mit g++ 4.1.2 so). Besitzt eine normale Allokatorklasse überhaupt die Fähigkeit des Vergrößern bzw. Verkleinerns des Speicherbereichs? Und selbst wenn, es werden sich so keine system- und compilerunabhängige Allokatoren mit dieser Fähigkeit schreiben lassen: Die müssten entweder auf Betriebssystemfunktionen oder auf realloc() + manuelles Aufrufen des Konstruktors zurückgreifen. Hab Allokatoren noch nie benutzt, also lasse ich mich gerne eines Besseren belehren. <nicht ganz ernst gemeinte ironie> Schön, dass wir nochmal eine Abstraktionsschicht für die Speicherverwaltung haben, damit können wir jetzt unsere Abstraktionsschicht für die Abstraktion der Abstraktion abstrahieren ;)</ironie>



  • Nur am Rande: Die Allokatoren trennen sowieso die Speicheranforderung und Konstruktion von Objekten in zwei getrennte Methoden. (und ein vector<> verbessert seine Performance idR, indem er mehr Speicher anfordert als er aktuell benötigt).



  • Ganz erlich, ich verwende so gut wie nie ein new[]. Eigentlich gar nicht. deswgen interessiere ich mihc eigentlich auhc nicht für eine realloc-Alternative.


Anmelden zum Antworten