"Komfort" bei malloc



  • heyhoi schrieb:

    Ich hab den thread gelesen aber ich verstehe nicht wieso 0 bytes auch eine größe ist. was wird da angefordert?

    Nichts. Was die Gnu libc tut, kannst du getrost ignorieren, ist ja keine Referenz-Implementation. Den Speicher verbraucht in dem Fall grossteils/ausschliesslich der Overhead.
    🙂



  • Wird malloc() mit der Länge 0 aufgerufen ist vorher etwas schiefgelaufen.
    Der Fall sollte normaerweise nicht auftreten bzw es sollte vorher geprüft
    und reagiert werden.

    Kann das OS den Speicher nicht bereitstellen ist es so gut wie immer
    sinnfrei, das Programm weiterlaufen zu lassen. Wozu auch ?
    Also: exit() und raus.

    Da der Fall äußerst selten vorkommt (ok, bei mir. Mag bei anderen anders
    aussehen) ignoriere ich "Nebeneffekte". Da soll sich das OS drum kümmern.



  • Scheppertreiber schrieb:

    Kann das OS den Speicher nicht bereitstellen ist es so gut wie immer
    sinnfrei, das Programm weiterlaufen zu lassen. Wozu auch ?
    Also: exit() und raus.

    Na weil es vielleicht möglich sein sollte, dass ein bestimmter Programmteil aus irgendwelchen Gründen wie z.B. auch "nicht genug Speicher" nicht ausgeführt werden kann, ohne dass gleich die ganze Software böse abschmiert. Dann lieber die Rückgabe prüfen und ggf. eine Meldung raushauen, damit der User Bescheid weiß, aber nicht gleich den ganzen Prozess abschießen.



  • _matze schrieb:

    Na weil es vielleicht möglich sein sollte, dass ein bestimmter Programmteil aus irgendwelchen Gründen wie z.B. auch "nicht genug Speicher" nicht ausgeführt werden kann, ohne dass gleich die ganze Software böse abschmiert. Dann lieber die Rückgabe prüfen und ggf. eine Meldung raushauen, damit der User Bescheid weiß, aber nicht gleich den ganzen Prozess abschießen.

    Ok, das hängt von ... ab. In den meisten Fällen hat es ja einen Grund, Speicher
    vom OS anzufordern. Klar sind Fälle denk- und konstruierbar wo das Programm auch
    ohne weiterlaufen oder sich kontrolliert beenden kann. Nur, bevor ich mir Daten
    schieße, lieber abbrechen und nach der Ursache suchen und diese beheben.



  • Scheppertreiber schrieb:

    _matze schrieb:

    Na weil es vielleicht möglich sein sollte, dass ein bestimmter Programmteil aus irgendwelchen Gründen wie z.B. auch "nicht genug Speicher" nicht ausgeführt werden kann, ohne dass gleich die ganze Software böse abschmiert. Dann lieber die Rückgabe prüfen und ggf. eine Meldung raushauen, damit der User Bescheid weiß, aber nicht gleich den ganzen Prozess abschießen.

    Ok, das hängt von ... ab. In den meisten Fällen hat es ja einen Grund, Speicher
    vom OS anzufordern. Klar sind Fälle denk- und konstruierbar wo das Programm auch
    ohne weiterlaufen oder sich kontrolliert beenden kann. Nur, bevor ich mir Daten
    schieße, lieber abbrechen und nach der Ursache suchen und diese beheben.

    Daraus lässt sich schliessen, dass Programme, die unbedingt immer laufen müssen, malloc nicht benutzen dürfen.



  • Wieso ?



  • Scheppertreiber schrieb:

    Wieso ?

    Gamz einfach:
    Wenn malloc scheitert, dann kann das Programm nicht vernünftig weiterarbeiten => Ein Programm, das ohne Störungen laufen soll, darf nicht auf malloc angewiesen sein.



  • collam schrieb:

    Scheppertreiber schrieb:

    Wieso ?

    Gamz einfach:
    Wenn malloc scheitert, dann kann das Programm nicht vernünftig weiterarbeiten => Ein Programm, das ohne Störungen laufen soll, darf nicht auf malloc angewiesen sein.

    Blödsinn. Wenn malloc scheitert, kann das auch nur bedeuten, dass ein bestimmter Zweig nicht ausgeführt werden kann. Deswegen die ganze SW abzuschiessen ist natürlich Quatsch, wenn der Benutzer doch weiterhin nutzen aus all den anderen Zweigen ziehen kann. Wenn man beispielsweise einen Editor mit vielen Freiheiten, was Speicherverbrauch angeht, bereitstellt, dann kann es durchaus passieren, dass der Benutzer soviele Felder platziert, bis kein Speicher mehr alloziert werden kann. Dann schlägt malloc fehl, er wird darüber informiert, der Editor läuft aber weiterhin und er kann noch weiterarbeiten (Datei speichern, vielleicht auch Felder löschen usw.).



  • Ich hatte auch mal so ein Phänomen bei einem Parser, der am PC lief und auf einem Controller crashte. Grund war tatsächlich das malloc(0), das sich unterschiedlich verhielt.

    Bevor ich mich mit dem "unique" Pointer für die Blocksize 0 abplage, die dann ja wieder nur auf einem Compiler funktionieren würde, habe ich malloc(0) als Fall aussortiert, obwohl logisch kein Fehler dahintersteckte, wenn malloc(0) auf allen Kisten NULL zurückgeliefert hätte. Ist aber in der bösen Realwelt leider nicht so. 😃

    Nochwas: Wenn man Pointer immer mit NULL initialisiert und beim free() wieder auf NULL setzt, kann eigentlich nichts schiefgehen und vereinfacht den cleanup.

    collam schrieb:

    Wenn malloc scheitert, dann kann das Programm nicht vernünftig weiterarbeiten => Ein Programm, das ohne Störungen laufen soll, darf nicht auf malloc angewiesen sein.

    Bullshit. Wenn malloc() fehlschlägt, heißt das, daß kein Speicher mehr frei ist, nicht mehr und nicht weniger. Bei obig erwähntem Parser gibt's den Fall auf dem Controller mehrfach und bedeutet nur, daß ich die Befehlsketten, die im Speicher schon bearbeitet sind, auf die SD- Karte weggeschrieben und gefreed werden sollen. Das ist keine Störung. 🤡



  • _matze schrieb:

    Blödsinn. Wenn malloc scheitert, kann das auch nur bedeuten, dass ein bestimmter Zweig nicht ausgeführt werden kann.

    Du vergisst, dass der gesamte Prozess nur diese eine Speicherverwaltung hat. Es können dann auch andere Zweige nicht mehr funktionieren, die den Heap benutzen. Weisst du genau, dass keine API-Funktion Speicher alloziert, die in anderen Zweigen benutzt wird?



  • collam schrieb:

    _matze schrieb:

    Blödsinn. Wenn malloc scheitert, kann das auch nur bedeuten, dass ein bestimmter Zweig nicht ausgeführt werden kann.

    Du vergisst, dass der gesamte Prozess nur diese eine Speicherverwaltung hat. Es können dann auch andere Zweige nicht mehr funktionieren, die den Heap benutzen. Weisst du genau, dass keine API-Funktion Speicher alloziert, die in anderen Zweigen benutzt wird?

    Und du vergisst, dass das Fehlschlagen von malloc(100000000) nicht bedeuten muss, dass andere Funktionen nichts mehr vom Heap abkriegen. :p



  • collam schrieb:

    Du vergisst, dass der gesamte Prozess nur diese eine Speicherverwaltung hat. Es können dann auch andere Zweige nicht mehr funktionieren, die den Heap benutzen. Weisst du genau, dass keine API-Funktion Speicher alloziert, die in anderen Zweigen benutzt wird?

    Versuch's mal mit was anderem, als Schwachsinnigkeit zu demonstrieren. :p

    Ein Zweig kriegt keinen Speicher mehr, heißt aber nicht zwangsläufig, daß die Kiste mitm Memleak abkackt.
    Der gleiche Parser (sh. letzte Beiträge) läuft auf Kisten mit 32kB Heap genauso wie mit 256 MB Heap, nur daß der PC nicht zwischendurch abräumen muß, der Controller das bei gleicher Filegröße ein paar hundert mal machen muß. Er ist einfach nur skalierbar programmiert. 😉



  • _matze schrieb:

    Und du vergisst, dass das Fehlschlagen von malloc(100000000) nicht bedeuten muss, dass andere Funktionen nichts mehr vom Heap abkriegen.

    Ich dachte mehr an einen Zustand der Fragmentierung, wobei noch nicht mal mehr 0x1000 Bytes möglich sind. Aber auch wenn "nur" Deine 100000000-Bytes Allokation nicht funktioniert, brauchst Du eine Ausweichmöglichkeit. Tatsache ist: Dein Programm kann sich, wenn Du malloc verwendest, zu einem unvorhersehbaren Zeitpunkt anders verhalten als sonst.



  • collam schrieb:

    zu einem unvorhersehbaren Zeitpunkt anders verhalten als sonst.

    Das ist bei C immer mal drin 🙂

    Eigentlich verwende ich malloc() recht selten, meist, wenn ich eine Datei komplett
    lesen will und vorher nicht weiß wie groß die sein könnte (dann: Größe ermitteln,
    malloc und laden). Ansonsten aus Laufzeitgründen meist statische Arrays (dramatisch
    schneller als jeden Record mit malloc anzulegen). Sollte da etwas schiefgehen, kann
    ich die Daten auch nicht weiterverarbeiten -> Abbruch.

    Bastele ich ein Programm, das auf Eingaben reagiert (zB Webserver) sieht die
    Geschichte völlig anders aus. Dort laufe ich aber mit der Zeit in einen sauber
    zerlegten und fragmentierten Heap der die Sache auch nicht besser macht.

    Bei einem netten kleinen uC (etwa PIC) kann ich mir malloc eh schenken ...



  • collam schrieb:

    Ich dachte mehr an einen Zustand der Fragmentierung, wobei noch nicht mal mehr 0x1000 Bytes möglich sind.

    Das ist aber nur einer der möglichen Fälle. Nur anhand dessen kann man keine allgemeingültige Aussage darüber treffen, ob nach Fehlschlagen von malloc ein Weiterführen des Programms sinnvoll sein könnte.

    collam schrieb:

    Aber auch wenn "nur" Deine 100000000-Bytes Allokation nicht funktioniert, brauchst Du eine Ausweichmöglichkeit.

    Was meinst du mit Ausweichmöglichkeit? Wenn ich einen bestimmten Programmteil nicht ausführen kann, weil die dafür nötige, vielleicht sehr große Allokation nicht möglich ist, informiere ich den Benutzer und starte diesen Programmteil nicht. Das wäre dann irgendwie das ausweichen, ja? Wenn dann natürlich durch kaum mehr verfügbaren/stark fragmentierten Speicher wirklich keine Allokation mehr klappt, wird der Benutzer halt einfach kaum noch Funktionen ausführen können und sich ständig über "out of memory" Meldungen ärgern. 😉 Dann ist natürlich ein Beenden der SW nötig. Und dieser Fall bedeutet dann auch, dass die SW genausogut hätte abschmieren können (in beiden Fällen kann der Benutzer mit der Software nix mehr anfangen). Ich finde halt nur, dass man den erstgenannten Fall auch bedenken und in der SW berücksichtigen sollte, falls das dem Benutzer was bringen kann.



  • So ist es, Matze.

    Sieh es aus Benutzersicht: Macht es überhaupt Sinn, das Programm weiterlaufen
    zu lassen (falls es technisch möglich ist) ?

    Dann: Wieso kommt es eigentlich zu der übergroßen Speicheranforderung ? Ist da
    vielleicht vorher irgendetwas nicht auf Plausibilität geprüft worden ? Macht der
    Benutzer Unfug (wie zB 100000 Fotos im RAW-Format laden) ?


Anmelden zum Antworten