Muss nach der Speicherzuweisung auf NULL geprüft werden, wenn der Kernel Overcommit-Speicher verwendet?

StackOverflow https://stackoverflow.com/questions/2248995

  •  20-09-2019
  •  | 
  •  

Frage

Es ist allgemeine Praxis, nach einem malloc() auf NULL zu prüfen (ob Speicher erfolgreich zugewiesen wurde), so etwas wie

void *ptr = malloc(10);    
if (ptr != NULL) {  
  // do some thing usefull  
} else {  
 // no memory. safely return/throw ...  
}  

Besteht bei aktivierter Speicherüberbelegung im Kernel die Möglichkeit, dass NULL angezeigt wird?Sollte ich der Praxis folgen, NULL für jede Zuweisung religiös zu überprüfen?Wird malloc trotz des aggressiven Overcommit-Mechanismus NULL zurückgeben (ich vermute Wert 1)?

Tatsächlich verwendet der Android-Kernel eine Speicherüberbelegung (ich bin mir über den Wert nicht sicher, würde ihn gerne wissen (Überbelegungswert) und seine Bedeutung).Ein Teil des Framework-Quellcodes (C/C++) in Android (möglicherweise von Drittanbietern) prüft nicht auf NULL und fängt bad_alloc nach Zuweisungen nicht ab.Vermisse ich etwas?

Es gibt in SO einige Threads zum Thema Overcommit-Speicher, aber keiner davon hat meine Verwirrung gelöst.

BEARBEITEN: Wenn aggressives Overcommit verwendet wird, wird NULL nicht zurückgegeben (Annahme 1).Wenn kein physischer Speicher verfügbar ist und versucht wird, auf den zugewiesenen Speicher zuzugreifen (in den zugewiesenen Speicher zu schreiben), beendet OOM einen Prozess und weist der Anwendung Speicher zu, bis diese wiederum beendet wird (Annahme 2).In beiden Fällen sehe ich keine Notwendigkeit, NULL zu überprüfen (Speicher wird zugewiesen oder Prozess wird abgebrochen).Liege ich mit meinen Annahmen richtig?
Portabilität ist bei dieser Frage kein Problem.

War es hilfreich?

Lösung

Ja, Sie sollten trotzdem nach Fehlern suchen, die von zurückgegeben wurden malloc.In einer Umgebung, in der der Speicher überlastet ist, können Sie Fehler nicht erkennen und beheben, da die Umgebung nicht mehr über den erforderlichen physischen Speicher verfügt, wenn Sie in Teile des Adressraums schreiben, die Ihrem Programm durch einen vorherigen Aufruf von zugewiesen wurden malloc.

Dies ist jedoch nicht das einzige Problem, das a verursachen würde malloc in einem traditionellen Umfeld scheitern.Eine Anforderung eines besonders großen Speicherblocks, wenn der Adressraum Ihres Programms fragmentiert ist, kann fehlschlagen, selbst wenn potenziell genügend physischer Gesamtspeicher vorhanden ist, um die Anforderung zu erfüllen.Denn es gibt keinen zusammenhängenden Bereich an freiem Adressraum malloc muss scheitern.Diese Art von Fehler muss durch signalisiert werden malloc zurückkehren NULL, unabhängig davon, ob die Umgebung den Speicher überbelegt oder nicht.

Andere Tipps

Sie müssen den Rückgabewert auf NULL überprüfen jeden Zeit.Jede Bibliotheksfunktion kann fehlschlagen.Sogar fclose() funktioniert (bei getrennter NFS-Freigabe und ein Fehler von fclose der NFS-Datei bedeutet, dass die Daten nicht gespeichert wurden).

Die meiste Software ist schlecht geschrieben und enthält nicht alle Prüfungen.

malloc kann nichts anderes als NULL oder einen Zeiger zurückgeben.Alles oder nichts.Sie können von malloc kein 1 Byte erhalten, wenn Sie nach 10 fragen.

Es wäre ratsam, bei allen Funktionsaufrufen, die möglicherweise NULL zurückgeben, regelmäßig auf NULL zu prüfen, unabhängig davon, ob der Kernel über überbeschreibbaren Speicher verfügt oder nicht.

Das folgende Codesegment unten zeigt, wie Sie überprüfen können, ob der Anruf an erfolgt malloc hat funktioniert oder nicht...

void *ptr = malloc(10);
if (ptr != NULL){
   /* Do something here with ptr */
}else{
   /* Do something here if it fails */
}

Dateioperationen und Speicheroperationen, um nur einige zu nennen, geben bei einem Fehler NULL zurück.

Hoffe das hilft, am besten, Tom.

Nun ja ... unter Linux wird es dem Betriebssystem immer gelingen, Ihnen Speicher zur Verfügung zu stellen, da der Speicher (zunächst) nicht durch Seiten gesichert ist und erst nach dem ersten Lesen/Schreiben eine Seitensicherung erstellt (es sei denn, Sie haben den Adressraum erschöpft, was in 64-Bit-Systemen nicht möglich ist). ).Wenn also der Speicher ausgeht und Sie nicht den versprochenen Speicher erhalten können, beendet der OOM-Killer einfach Ihre Anwendung oder eine andere Anwendung, um Ihnen die Seitenunterstützung zu geben, die Sie benötigen.Unabhängig davon, ob Sie die NULL-Prüfung durchführen oder nicht, ist das Ergebnis dasselbe: ein Absturz.......

Nein, es ist nicht erforderlich, das Ergebnis von malloc zu überprüfen.

Lange bevor malloc scheiterte, hatte das Betriebssystem bereits viele Probleme.

„OOM-Killer und Overcommit“ wäre die bessere Wahl.

Was?Ihr Betriebssystem unterstützt „OOM-Killer und Overcommit“ nicht?

Deshalb sollten Sie auf Linux (oder Android) umsteigen!

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top