new und realloc



  • firefly schrieb:

    Ich habe dir nun bewiesen, anhand der implementationen von 2 großen Compiler Hersteller, das new indirekt malloc(beim MSCRT ist das die funktion _heap_alloc) aufruft.

    Und wozu soll das gut sein? Niemand hat derartige Beweise verlangt. Zudem bleibt die Referenz der Standard. Wenn du also etwas beweisen willst, dann nur anhand dieses Dokumentes.

    firefly schrieb:

    Von dir/euch kam bis jetz kein wirklicher beweis, das meine Behauptung überhaupt
    nicht simmt.

    Wozu etwas beweisen, was überhaupt nicht relevant ist?

    firefly schrieb:

    Und groovemaster da anscheinent die MSCRT das auch so macht, ist dein argument, "das wir nicht für einen einzigen Compiler entwickeln" auch nicht haltbar.

    Wenn du schon zitierst, dann bitte richtig. Das habe ich so nie gesagt. Ich sprach von "konkretem Compiler bzw. konkreter Implementation". Und das kann auch mehr als eins sein. Natürlich gibt es Situationen, wo man sich von bestimmten Werkzeugen abhängig macht und dies auch bewusst in Kauf nimmt. Nur sollte man das nicht tun, wenn es nicht nötig ist. Und hier ist es nicht nötig. Wenn du realloc verwenden willst, dann überlade Operator new/delete. So wie es bereits mehrfach gesagt wurde. Dann hast du das Speichermanagement in deiner Hand und fertig.

    firefly schrieb:

    Aber das ganze interessiert eigentlich einen c/c++ programmiere überhauptnicht wie genau new und malloc implementiert ist.

    Das sagt doch schon alles. Und lässt alle anderen Ausführungen deinerseits bedeutungslos werden. Die Implementation interessiert uns nicht. Und deshalb wissen wir auch nichts darüber. Eben eine Black Box. Ob du hier irgendwas beweisen willst, ob dieser oder jener Compiler malloc aufruft, tut überhaupt nichts zur Sache.

    firefly schrieb:

    Wie schon gesagt, man kann malloc und new mischen, solange keine klassen-objekte ins spiel kommen.

    Ich kann auch Nullzeiger dereferenzieren. Oder String Literale beschreiben. Oder über die Grenzen eines Arrays hinaus lesend bzw. schreibend zugreifen. Und was bringt uns das am Ende des Tages? Exakt nichts! Nur kaputte Programme. Die am Anfang vllt. zu funktionieren scheinen. Dir aber spätestens am Tag X sämtliche Rechnerinnereien um die Ohren hauen werden.

    firefly schrieb:

    malloc und new sind bis auf den punkt mit Klassen-objekten nahezu identisch

    Nur noch was kurz dazu, da das auch immer wieder ungenau wiedergegeben wird. Genau genommen sind new und malloc, genauso wie delete und free, zwei verschiedene Sachen. Das C++ Gegenstück zu malloc nennt sich Operator new bzw. zu free Operator delete. Und das ist nur ein Teil von new bzw. delete. Dieser kleine aber feine Unterschied ist wesentlicher Bestandteil des dynamischen Speicherkonzeptes von C++. Die Denkweise muss dementsprechend eher dahin gehen, dass dieser Unterschied für PODs in der Praxis nicht zum Tragen kommt. Und nicht, dass "malloc und new bis auf Klassen-objekte nahezu identisch sind".



  • groovemaster da du anscheinent eh alles besser weist dann sage mir wiso sich new und malloc auser in dem punkt unterscheiden, das bei new der passende Constructor aufgerufen wird wenn man ein Objekt einer Klasse erzeugt?

    Meinem wissen nach, sind malloc und new beides konstrukte/funktionen mit dem man dynamische Speicher bei bedarf vom System anfordern kann.

    Wo genau soll sich denn das dynamische Speicherkonzept von c++ gegenüber c unterscheiden?

    Bei beiden "Funktionen" wird der angeforderte Speicher auf dem heap reserviert.

    Der einzigste unterschied den ich sehe ist der, das bei new dafür gesorgt wird, das bei non-POD Objekten nach dem anfordern des Speichers für das Objekt als solches (ohne den dynamischen anteil),
    eine entsprechende Konstruktions-phase ausgeführt wird (z.b. Aufruf des Constructors bei Klassen-objekten), um dem Objekt zu einem zu ermöglichen sein dynamischen anteil korrekt zu erzeugen und seine Datenmember zu initialisieren.

    Für delete sehe ich das genauso, nur das hier halt vor dem freigeben des Speicherbereiches für das Objekt als solches(ohne dymaischen anteil) eine Destruktions-phase ausgeführt wird, damit das Objekt seinen Dynamischen anteil (falls vorhanden)sauber freigeben kann oder andere "Aufräumarbeiten" noch erledigen kann.

    Wenn es noch andere unterschiede gibt, dann erleuchte einen, aus deiner sicht, unwissenden.



  • firefly schrieb:

    Bei beiden "Funktionen" wird der angeforderte Speicher auf dem heap reserviert.

    es können aber zwei verschiedene heaps sein. wenn vc und gcc den gleichen heap benutzen, hat das garnix zu bedeuten. bereits in der nächsten version kann's anders sein...
    :xmas2:



  • Letztenendes muss so oder so der entsprechende Syscall des jeweiligen Betriebssystem aufgerufen werden. In der Operator new Implementierung malloc aus der libc zu benutzen wäre nur einfacher.

    ten schrieb:

    firefly schrieb:

    Bei beiden "Funktionen" wird der angeforderte Speicher auf dem heap reserviert.

    es können aber zwei verschiedene heaps sein. wenn vc und gcc den gleichen heap benutzen, hat das garnix zu bedeuten. bereits in der nächsten version kann's anders sein...
    :xmas2:

    Häh? Speicherverwaltung macht immer noch der Kernel. Oder welches OS benutzt Du? 😉



  • /. schrieb:

    Letztenendes muss so oder so der entsprechende Syscall des jeweiligen Betriebssystem aufgerufen werden. In der Operator new Implementierung malloc aus der libc zu benutzen wäre nur einfacher.

    ten schrieb:

    firefly schrieb:

    Bei beiden "Funktionen" wird der angeforderte Speicher auf dem heap reserviert.

    es können aber zwei verschiedene heaps sein. wenn vc und gcc den gleichen heap benutzen, hat das garnix zu bedeuten. bereits in der nächsten version kann's anders sein...
    :xmas2:

    Häh? Speicherverwaltung macht immer noch der Kernel. Oder welches OS benutzt Du? 😉

    Sehe ich genauso, zum einen ist es einfacher und zum anderen erleichtert es auch etwas die Portierung auf andere Systeme.



  • /. schrieb:

    Häh? Speicherverwaltung macht immer noch der Kernel.

    das schon, aber zwischen einem programm das 'malloc' aufruft und 'nem kernel steckt z.b. noch das da: http://www.google.com/codesearch?hl=en&q=show:34YhoWHC2xk:Wic0kmEku8Q:8S_L_5n1bQM&sa=N&ct=rd&cs_p=http://www.tivo.com/linux/TiVo-many-powerpc-devenv.tar.gz&cs_f=libc/new-malloc/malloc.c
    jetzt könnte ja ein compilercoder auf die idee kommen, für den c++ new operator sowas zu nehmen: http://www.keil.com/download/docs/18.asp
    und schon passt es nicht mehr zusammen...
    :xmas2:



  • firefly schrieb:

    ...
    Meinem wissen nach, sind malloc und new beides konstrukte/funktionen mit dem man dynamische Speicher bei bedarf vom System anfordern kann..

    Ja und mein Fahrrad und eine F16 sind beide dazu da, Menschen fortzubewegen - da ist nur diese kleine "Flugsache" ... ansonsten sind sie gleich. 😉

    Du willst es nicht einsehen und deswegen wirst Du Dich selbst bei einem "1 != 0"-Beweis noch sträuben und das ist OK, Du solltest nur diese Enscheidung zur Lernresistenz nicht als "objektiven Beweis" für Deine These ansehen.
    Hier 2 Aussagen, die das Thema IMO auf den Punkt bringen:

    • C++ definert als operatoren für die dynamische Speicherverwaltung new/delete un beschreibt ihr Verhalten.
    • C++ unterstützt als Kompatibilitätszugeständnis an C noch malloc()/realloc() im C-Sinne - trifft aber keine Aussagen darüber, wie die mit new/delete zusammenhängen.

    Wer mag, darf sich gerne der "lex firefly" anvertrauen und das nach Belieben mischen - ich lasse das lieber (oder spare es mir für wirklich verzweifelte Situationen auf).

    BTW: zur ursprünglichen Fragestellung: Könnte ein "placement-new" nicht helfen ?

    Gruß,

    Simon2.



  • ten schrieb:

    /. schrieb:

    Häh? Speicherverwaltung macht immer noch der Kernel.

    das schon, aber zwischen einem programm das 'malloc' aufruft und 'nem kernel steckt z.b. noch das da: http://www.google.com/codesearch?hl=en&q=show:34YhoWHC2xk:Wic0kmEku8Q:8S_L_5n1bQM&sa=N&ct=rd&cs_p=http://www.tivo.com/linux/TiVo-many-powerpc-devenv.tar.gz&cs_f=libc/new-malloc/malloc.c
    jetzt könnte ja ein compilercoder auf die idee kommen, für den c++ new operator sowas zu nehmen: http://www.keil.com/download/docs/18.asp
    und schon passt es nicht mehr zusammen...
    :xmas2:

    Stimmt, der kernel verwaltet den kompletten verfügbaren Arbeitsspeicher, wobei man auch den "Swapspeicher" mit dazu zählen muss.
    Soweit ich das weis, bekommt jeder Prozess vom kernel eine gewisse größe an maximal verfügbaren "Arbeitsspeicher" zugeteilt. Diese größe ist vom Betriebsystem und dem verfügbaren realen Speicher abhängig, z.b. Unter Windows bekommt jeder Prozess ca. 2GB/4GB.

    Dieser verfügbaren Speicherblock wird aber andererseits bestimmt von der C/C++-Runtime verwaltet.
    Der Compiler als solches hat garnichts mit der Speicherverwaltung zu tun. Wie sollte er auch, da er ja zur compile-zeit nicht wissen kann auf welchem System das Kompilat später laufen wird und wieviel speicher dort verfügbar ist.

    z.b. Ein programm wurde unter Win98 erstellt und übersetzt und wird später aber unter WinXP ausgeführt.
    Ich glaube jeder wird mir zustimmen, das sich das Memory-Management zwischen Win98 und WinXP stark unterscheidet.

    Damit dies funktioniert gibt es ja die C-library bzw. die C++-library(wobei diese intern auch c-funktionen verwenden kann). Welche sich um das Memory-Management innerhalb eines Prozesses kümmert.

    Aber das hat nichts mit der Tatsache zu tun, das in der new-implementation eine C-Library-funktion(z.b. malloc) verwendet werden kann(der ISO-c++ Standard hat dies nicht verboten) und dies auch von 2 großen Compiler-/C++-Runtime-Herstellern (gcc, MSVC) so gemacht wird.
    Die Implementation kann aber auch auf die Verwendung von malloc bzw. C-Library-funktionen verzichten.
    Es spricht zumindestens ein guter Grund dafür, das man die C-Library-funktionen verwendet:
    - Man vermeidet code-duplication, da sich die Art und Weise, wie Speicher vom System reserviert wird, bei beiden identisch ist. Und ich spreche von der reinen Reservierung.

    Der Nachteil dafür ist aber, das die C++-Library von der C-Library abhängig ist.
    Aber dieser Nachteil ist in meinen Augen vernachlässigbar, da eine reine C++-Runtime-Library in meinen augen sinnlos ist.
    Es würde nur unnötig code-duplication bedeuten, ganz besonders wenn auf einem system eh die c-library vorhanden ist.

    Ich stelle die Behauptung auf, das sich auf jedem system, welches eine dynamische Memory-Management bietet, auf jedenfall die C-Runtime vorhanden ist.
    Da C++ zu großen overhead gegenüber C bedeutet, für Hardwarenahe Programmierung.

    Also im prinzip kann man malloc und new mischen.
    Aber, wie schon öfters in diesem Thread gesagt wurde, sollte man dies nicht tun, da zum einen die Konstruktions-phase bei Klassen-Objekten nicht ausgeführt wird, wenn man anstelle von new, malloc verwendet. Und zum anderen kann es zu Problemen zur Laufzeit kommen, wenn die C/C++-Runtime das mischen nicht gestattet.



  • Simon2 schrieb:

    firefly schrieb:

    ...
    Meinem wissen nach, sind malloc und new beides konstrukte/funktionen mit dem man dynamische Speicher bei bedarf vom System anfordern kann..

    Ja und mein Fahrrad und eine F16 sind beide dazu da, Menschen fortzubewegen - da ist nur diese kleine "Flugsache" ... ansonsten sind sie gleich. 😉

    Du willst es nicht einsehen und deswegen wirst Du Dich selbst bei einem "1 != 0"-Beweis noch sträuben und das ist OK, Du solltest nur diese Enscheidung zur Lernresistenz nicht als "objektiven Beweis" für Deine These ansehen.
    Hier 2 Aussagen, die das Thema IMO auf den Punkt bringen:

    • C++ definert als operatoren für die dynamische Speicherverwaltung new/delete un beschreibt ihr Verhalten.
    • C++ unterstützt als Kompatibilitätszugeständnis an C noch malloc()/realloc() im C-Sinne - trifft aber keine Aussagen darüber, wie die mit new/delete zusammenhängen.

    Wer mag, darf sich gerne der "lex firefly" anvertrauen und das nach Belieben mischen - ich lasse das lieber (oder spare es mir für wirklich verzweifelte Situationen auf).

    BTW: zur ursprünglichen Fragestellung: Könnte ein "placement-new" nicht helfen ?

    Gruß,

    Simon2.

    Öhm ich habe nie gesagt, das man das tun soll, sondern nur das es im prinzip möglich ist, zumindestend bei der momentanen implementation der C++-Runtime unter Windows und Linux.

    Ich habe desweiteren mehrmals gesagt, das man dies nicht tun soll.

    Aber das hast do wohl einfach überlesen.



  • Simon2 schrieb:

    Hier 2 Aussagen, die das Thema IMO auf den Punkt bringen:

    • C++ definert als operatoren für die dynamische Speicherverwaltung new/delete un beschreibt ihr Verhalten.
    • C++ unterstützt als Kompatibilitätszugeständnis an C noch malloc()/realloc() im C-Sinne - trifft aber keine Aussagen darüber, wie die mit new/delete zusammenhängen.

    Ach ja das der c++-Standard darüber keine Aussagen macht kann ich dir nicht glauben. Oder ist das etwa für dich keine Aussage, wenn es in dem Implementator selbst überlassen ist, ob er malloc verwenden möchte oder nicht?

    aus http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1905.pdf seite 401:

    void * operator new(std :: size_t size ) throw (std :: bad_alloc );
    1 Effects:The allocation function (3.7.3.1) called by a new-expression (5.3.4) to allocate size bytes of storage
    suitably aligned to represent any object of that size.
    2 Replaceable: a C++ program may define a function with this function signature that displaces the default version
    defined by the C++ Standard library.
    3 Required behavior: Return a non-null pointer to suitably aligned storage (3.7.3), or else throw a bad_alloc
    exception. This requirement is binding on a replacement version of this function.
    4 Default behavior:
    — Executes a loop: Within the loop, the function first attempts to allocate the requested storage. Whether the
    attempt involves a call to the Standard C library function malloc is unspecified.



  • firefly schrieb:

    Ach ja das der c++-Standard darüber keine Aussagen macht kann ich dir nicht glauben. Oder ist das etwa für dich keine Aussage, wenn es in dem Implementator selbst überlassen ist, ob er malloc verwenden möchte oder nicht?

    Whether the attempt involves a call to the Standard C library function malloc is unspecified.

    der c++ standard macht dazu die aussage, dass er dazu keine aussage macht 😉
    ➡

    unspecified



  • firefly schrieb:

    ...

    Simon2 schrieb:

    ...

    • ... trifft aber keine Aussagen darüber, wie die mit new/delete zusammenhängen.

    Ach ja das der c++-Standard darüber keine Aussagen macht kann ich dir nicht glauben. Oder ist das etwa für dich keine Aussage, wenn es in dem Implementator selbst überlassen ist, ob er malloc verwenden möchte oder nicht?

    ...

    void * operator new(std :: size_t size ) throw (std :: bad_alloc );
    ...
    Whether the attempt involves a call to the Standard C library function malloc is unspecified.

    Ja, er sagt, dass er keinen Zusammenhang spezifizert.
    Ergo: Du kannst Dich nicht darauf verlassen, dass new irgendetwas mit malloc zu tun hat. Außer dass er Dich persönlich mit Namen anspricht, hätte der Standard das wohl nicht deutlicher schreiben können.

    Übrigens: Wir sind schon ziemlich dicht dran am "0!=1"-Beweis .... 😃

    Gruß,

    Simon2.



  • ok ok das mit der aussage lag ich falsch.

    Aber Simon2, das du mir vorwirfst, das ich behaupten würde, das man malloc und new mischen soll ist falsch 😉 und das ich Lern-Resistent bin auch.

    Wie schon gesagt, der Standard macht keine Aussage ob in der new implementation malloc verwendet werden soll oder nicht.
    Aber das ändert nichts an der Tatsache, das man malloc und new mischen kann. Zumindestens in der momentan vorhandenen Implementationen von new durch die C++-Runtime von MS und der von GCC.

    Aber ich habe immer darauf hingewiesen, das man dies nicht tun soll und die Gründe dafür werde ich jetzt nicht nochmal wiederhohlen ;).

    Und mehr habe ich nie behauptet.

    Also das nächste mal erst komplett lesen was einer schreibt(wobei ich manchmal auch net besser bin ;)) und nicht in Versuchung kommen etwas hinein zu interpretieren, was der andere nicht gesagt/behauptet hat 🙂



  • firefly schrieb:

    Aber das ändert nichts an der Tatsache, das man malloc und new mischen kann.

    würdest du denn sowas machen?

    char *gimmethatfuckinmemory (int size)
    {
       char *mem = malloc(size);
       if (!mem)
          mem = new char[size];
       return mem;
    }
    

    :p



  • Hi,

    na, dann ist ja alles klar.
    Wenn Du natürlich auf eine Aussage "new und malloc sollte man nicht mischen" erwiderst "Kann man aber und steht nirgends !" - kann das schon als Aufforderung zum Gegenteil mißverstanden werden.
    Meiner Meinung jedenfalls leichter, als ein "unspecified" im Standard als "klappt meistens" 😉 ....

    Gruß,

    Simon2.



  • ten schrieb:

    firefly schrieb:

    Aber das ändert nichts an der Tatsache, das man malloc und new mischen kann.

    würdest du denn sowas machen?

    char *gimmethatfuckinmemory (int size)
    {
       char *mem = malloc(size);
       if (!mem)
          mem = new char[size];
       return mem;
    }
    

    :p

    oh man ich habe nie behauptet, das ich das mache, sondern nur das es im prinzip geht. Wiso liest hier mancher meine posts nie komplett durch. Habe ich etwa nen Schild umhängen "Lies nur nen teil was ich geschrieben habe und interpretiert dann fröhlich dinge hinzu." ??

    Aber so würde ich es überhaupt net machen, wenn malloc schon nichts bekommt wie sollte den new dann erfolgreicher sein?
    Da ja in der momentan vorhandenen Implementationen malloc und new auf den selben heap zugreifen.



  • Simon2 schrieb:

    Hi,

    na, dann ist ja alles klar.
    Wenn Du natürlich auf eine Aussage "new und malloc sollte man nicht mischen" erwiderst "Kann man aber und steht nirgends !" - kann das schon als Aufforderung zum Gegenteil mißverstanden werden.
    Meiner Meinung jedenfalls leichter, als ein "unspecified" im Standard als "klappt meistens" 😉 ....

    Gruß,

    Simon2.

    Hmm eventuell habe ich mich da etwas ungünstig in meinem 1. post ausgedrückt.
    Aber später habe ich das zumindestens teilweise korrigiert bzw. bewiesen, wie es momentan aussieht in den meistverbreiteten Implementationen von new (bei MS und GNU/Linux mit gcc).



  • firefly schrieb:

    Aber so würde ich es überhaupt net machen, wenn malloc schon nichts bekommt wie sollte den new dann erfolgreicher sein?

    ach ja, das ist ja ein und das selbe 😃
    was hälste denn davon?

    char *mix_it_baby (size_t size)
    {
       if (rand()%2)
          return (char*)malloc(size);
       return new char[size];
    }
    

    :xmas2:



  • ten schrieb:

    firefly schrieb:

    Aber so würde ich es überhaupt net machen, wenn malloc schon nichts bekommt wie sollte den new dann erfolgreicher sein?

    ach ja, das ist ja ein und das selbe 😃
    was hälste denn davon?

    char *mix_it_baby (size_t size)
    {
       if (rand()%2)
          return (char*)malloc(size);
       return new char[size];
    }
    

    :xmas2:

    moep mit dir brauch ich net weiter diskutieren, da du ja eh anscheinent meine posts nie komplett gelesen bzw. teile nicht verstanden hast.



  • firefly schrieb:

    groovemaster da du anscheinent eh alles besser weist dann sage mir wiso sich new und malloc auser in dem punkt unterscheiden, das bei new der passende Constructor aufgerufen wird wenn man ein Objekt einer Klasse erzeugt?

    malloc ist nichts weiter, als eine simple Funktion zur Speicherreservierung. new ist ein "Ausdruck", mit dem man dynamische Objekte erzeugen kann. Du kannst das nicht einfach so in einen Topf hauen. Erkläre mir doch mal, warum trotz deiner Aussage Folgendes unterschiedliches Verhalten hat:

    malloc(sizeof(int))
    new int()
    

    new lässt sich durch malloc vllt. am besten so beschreiben:

    void* p = malloc(sizeof(T));
    new (p) T;
    

    Deshalb ist einfach deine Denkweise falsch, dass "new und malloc gleich sind bis auf...". Das was malloc macht, ist nur ein Teil von dem, was new macht.

    firefly schrieb:

    Also im prinzip kann man malloc und new mischen.

    Du klingst schon fast wie der Leierkastenmann. Vllt. kannst du ja mal erklären, was du uns mit dieser Aussage mitteilen willst. Du kannst in C++ viel machen. Die Frage ist nur, ob es sinnvoll bzw. erlaubt ist. Und malloc und new zu mischen, ist nicht sinnvoll. Also lass es gut sein und versuche hier nicht irgendwas beweisen zu wollen, was überhaupt nicht relevant ist.


Anmelden zum Antworten