Wie groß ist die Wahrscheinlichkeit, dass Realloc fehlschlägt?

8

Scheitert es, wenn der freie Speicher nicht mehr ausreicht, wie in malloc , oder könnte es andere Gründe geben?

    
user963241 07.02.2011, 19:27
quelle

4 Antworten

10

Alle Zuordnungsfunktionen ( malloc , realloc , calloc und POSIX, posix_memalign ) können aus folgenden Gründen und möglicherweise auch anderen fehlschlagen:

  • Sie haben Ihren gesamten virtuellen Adressraum oder zumindest den nutzbaren Teil davon verbraucht. Auf einer 32-Bit-Maschine gibt es nur 4 GB Adressen, und möglicherweise ist 1 GB oder so für die Verwendung durch den Betriebssystemkernel reserviert. Selbst wenn Ihr Computer über 16 GB physischen Speicher verfügt, kann ein einzelner Prozess nicht mehr verwenden, als er für Adressen hat.
  • Sie haben Ihren virtuellen Adressraum nicht verbraucht, aber Sie haben ihn so stark fragmentiert, dass kein zusammenhängender Adressbereich der angeforderten Größe verfügbar ist. Dies kann passieren (auf einer 32-Bit-Maschine), wenn Sie erfolgreich 6 512MB-Blöcke zuweisen, alle anderen freigeben und dann versuchen, einen 1GB-Block zuzuweisen. Natürlich gibt es viele andere Beispiele mit kleineren Speichergrößen.
  • Ihr Computer hat keinen physischen Speicher mehr, entweder weil Ihr eigenes Programm alles verwendet hat oder andere Programme, die auf dem Rechner laufen, die alles genutzt haben. Einige Systeme (Linux in der Standardkonfiguration) werden überkomprimieren , was bedeutet, dass malloc in dieser Situation nicht fehlschlägt, stattdessen wird das Betriebssystem später ein oder mehrere Programme beenden, wenn es herausfindet, dass es nicht wirklich genug ist physischer Speicher, um herumzugehen. Aber auf robusten Systemen (einschließlich Linux mit deaktiviertem Overcommit) wird malloc fehlschlagen, wenn kein physischer Speicher mehr vorhanden ist.

Beachten Sie, dass streng genommen die Zuweisungsfunktionen aus irgendeinem Grund jederzeit fehlschlagen dürfen. Das Minimieren von Fehlern ist ein Qualitätsproblem. Es ist auch möglich, dass realloc fehlschlagen kann, auch wenn die Größe eines Objekts reduziert ; Dies könnte bei Implementierungen auftreten, bei denen die Zuteilungen streng nach Größe getrennt sind. Natürlich könnten Sie in diesem Fall einfach das alte (größere) Objekt weiter verwenden.

    
R.. 07.02.2011 19:37
quelle
4

Sie sollten sich realloc so vorstellen, dass Sie so arbeiten:

%Vor%

Eine Implementierung kann in der Lage sein, bestimmte Fälle effizienter durchzuführen, aber eine Implementierung, die genau wie gezeigt funktioniert, ist zu 100% korrekt. Das bedeutet realloc(ptr, newsize) kann jederzeit fehlschlagen malloc(newsize) wäre fehlgeschlagen; Insbesondere kann fehlschlagen, selbst wenn Sie die Zuweisung verringern .

Nun, auf modernen Desktop-Systemen gibt es gute Argumente dafür, nicht von malloc failures wiederherzustellen, sondern stattdessen malloc in eine Funktion (normalerweise xmalloc ) zu schreiben, die das Programm sofort beendet, wenn malloc fehlschlägt; Natürlich gilt das gleiche Argument für realloc . Der Fall ist:

  1. Desktop-Systeme laufen oft im "overcommit" -Modus, in dem der Kernel gerne mehr Adressraum ausgibt als mit RAM + swap gesichert werden kann, vorausgesetzt, das Programm wird nicht wirklich alles nutzen. Wenn das Programm versucht, alles zu verwenden, wird es zwangsweise beendet. Auf solchen Systemen wird malloc nur dann fehlschlagen, wenn Sie den -Adressraum erschöpfen, was auf 32-Bit-Systemen unwahrscheinlich und auf 64-Bit-Systemen nahezu unmöglich ist.
  2. Selbst wenn Sie nicht im Modus "Übergeben" sind, ist die Wahrscheinlichkeit groß, dass ein Desktop-System so viel RAM und Swap zur Verfügung hat, dass lange bevor Sie malloc zum Scheitern bringen, der Benutzer genug von seiner Thrash-Disk und beenden Sie Ihr Programm zwangsweise.
  3. Es gibt keinen praktischen Weg, test Wiederherstellung von einem Zuordnungsfehler zu überprüfen; Selbst wenn Sie eine Shim-Bibliothek hätten, die genau kontrollieren könnte, welche Aufrufe von malloc fehlgeschlagen sind (solche Shims sind im besten Fall schwierig, schlimmstenfalls unmöglich, abhängig vom Betriebssystem zu erstellen), müssten Sie die Reihenfolge 2 N testen Fehlermuster, wobei N die Anzahl der Aufrufe von malloc in Ihrem Programm ist.

Die Argumente 1 und 2 gelten (noch!) nicht für eingebettete oder mobile Systeme, aber das Argument 3 ist dort immer noch gültig.

Argument 3 gilt nur für Programme, bei denen Zuordnungsfehler an jeder Aufrufstelle überprüft und weitergegeben werden müssen. Wenn Sie so glücklich sind, C ++ so zu verwenden, wie es verwendet werden soll (d. H. Mit Ausnahmen), können Sie sich darauf verlassen, dass der Compiler die Fehlerkorrekturpfade für Sie erstellt, so dass der Testaufwand erheblich reduziert wird. Und in jeder höheren Sprache, die es heutzutage wert ist, verwendet zu werden, haben Sie sowohl Ausnahmen als auch einen Garbage Collector, was bedeutet, dass Sie sich keine Sorgen über Allokationsfehler machen können, selbst wenn Sie das wollten.

    
zwol 07.02.2011 19:53
quelle
1

Ich würde es meistens Implementierungsspezifisch sagen. Einige Implementierungen können sehr wahrscheinlich fehlschlagen. Einige haben möglicherweise andere Teile des Programms fehlgeschlagen, bevor Realloc wird. Sei immer defensiv und überprüfe, ob es scheitert.

Denken Sie daran, den alten -Zeiger freizugeben, den Sie erneut zuweisen wollten.

%Vor%

ist IMMER ein möglicher Speicherverlust.

Mach es immer so:

%Vor%     
Earlz 07.02.2011 19:32
quelle
0

Sie haben zwei Fragen.

Die Chancen, dass malloc oder realloc fehlschlagen, sind auf den meisten modernen Systemen vernachlässigbar. Dies tritt nur auf, wenn Sie keinen virtuellen Speicher mehr haben. Ihr System schlägt beim Zugriff auf den Speicher und nicht beim Reservieren fehl.

W.r.t Fehler realloc und malloc sind fast gleich. Der einzige Grund dafür, dass realloc möglicherweise zusätzlich fehlschlägt, ist, dass Sie ein schlechtes Argument angeben, also Speicher, der nicht mit malloc oder realloc oder vorher mit free d zugeordnet wurde.

Bearbeiten: Angesichts von Rs Kommentar. Ja, Sie können Ihr System so konfigurieren, dass es beim Zuweisen fehlschlägt. Aber vor allem, AFAIK, das ist nicht der Standard. Es benötigt Privilegien, um auf diese Weise konfiguriert zu werden, und als Anwendungsprogrammierer ist das nichts, auf das Sie sich verlassen können. Zweitens, selbst wenn Sie ein System haben, das auf diese Weise konfiguriert ist, wird dies nur dann fehlschlagen, wenn Ihr verfügbarer Swap-Speicherplatz aufgebraucht ist. Normalerweise wird Ihre Maschine lange vorher unbenutzbar sein: Sie wird mechanische Berechnungen auf Ihrer Festplatte durchführen (AKA Swapping).

    
Jens Gustedt 07.02.2011 19:35
quelle

Tags und Links