C Dynamische Speicherzuweisung

C Dynamische Speicherzuweisung bezieht sich auf die Leistung Manuellem Speichermanagement zum Dynamische Speicherzuweisung in dem C Programmiersprache über eine Gruppe von Funktionen in der C Standardbibliothek, nämlich Malloc, Realloc, CALLOC und frei.[1][2]

Das C ++ Die Programmiersprache umfasst diese Funktionen; Die Betreiber Neu und löschen Geben Sie ähnliche Funktionen an und werden von den Autoren dieser Sprache empfohlen.[3] Dennoch gibt es mehrere Situationen, in denen die Verwendung Neu/löschen ist nicht anwendbar, z. B. Müllsammlung Code oder leistungsempfindlichen Code und eine Kombination von Malloc und PlatzierungNeu kann anstelle der höheren Ebene erforderlich sein Neu Operator.

Viele verschiedene Implementierungen des tatsächlichen Speicherzuweisungsmechanismus, der von verwendet wird Malloc, stehen zur Verfügung. Ihre Leistung variiert sowohl in der Ausführungszeit als auch in der erforderlichen Speicher.

Begründung

Das C Programmiersprache Speicher verwaltet statisch, automatisch, oder dynamisch. Statische Variablen werden im Hauptspeicher, normalerweise zusammen mit dem ausführbaren Code des Programms, zugewiesen und bestehen für die Lebensdauer des Programms bestehen. Automatische Dauervariablen werden auf dem zugewiesen Stapel Und kommen und gehen Sie, wie Funktionen gerufen werden und zurückkehren. Für statische und automatische Variablen muss die Größe der Zuordnung sein Kompilierungszeit Konstante (mit Ausnahme des Falls von automatischen Arrays variabler Länge[4]). Wenn die erforderliche Größe erst bekannt ist, bis Laufzeit (Wenn beispielsweise Daten der willkürlichen Größe vom Benutzer oder einer Festplattendatei gelesen werden), ist die Verwendung von Datenobjekten fester Größe unzureichend.

Die Lebensdauer des zugewiesenen Gedächtnisses kann ebenfalls Bedenken verursachen. Weder statisches noch automatisches Speicher sind für alle Situationen ausreichend. Automatisch zugeteilte Daten können nicht über mehrere Funktionsaufrufe hinweg bestehen, während statische Daten über die Lebensdauer des Programms bestehen, unabhängig davon, ob sie benötigt werden oder nicht. In vielen Situationen erfordert der Programmierer eine größere Flexibilität bei der Verwaltung der Lebensdauer des zugewiesenen Speichers.

Diese Einschränkungen werden durch Verwendung vermieden Dynamische Speicherzuweisung, in welchem ​​Gedächtnis explizit (aber flexibler) verwaltet wird, typischerweise, indem er ihn aus dem zuordnet Kostenloser Laden (informell als "Haufen" bezeichnet), ein Speicherbereich zu diesem Zweck strukturiert. In C die Bibliotheksfunktion Malloc wird verwendet, um einen Speicherblock auf dem Haufen zuzuweisen. Das Programm greift über a auf diesen Speicherblock zu Zeiger das Malloc kehrt zurück. Wenn der Speicher nicht mehr benötigt wird, wird der Zeiger an übergeben frei Das trifft das Speicher so, dass er für andere Zwecke verwendet werden kann.

Die ursprüngliche Beschreibung von C zeigte darauf hin CALLOC und cfree waren in der Standardbibliothek, aber nicht in der Standardbibliothek Malloc. Code für eine einfache Modellimplementierung eines Speichermanagers für Unix wurde mit gegeben Alloc und frei als Benutzeroberfläche fungiert und verwendet die SBRK Systemanruf, um Speicher aus dem Betriebssystem anzufordern.[5] Die 6. Ausgabe Unix -Dokumentation gibt Alloc und frei als Low-Level-Speicherzuweisung funktioniert.[6] Das Malloc und frei Routinen in ihrer modernen Form werden im UNIX -Handbuch der 7. Ausgabe vollständig beschrieben.[7][8]

Einige Plattformen bieten Bibliothek oder Intrinsische Funktion Anrufe, die die dynamische Allokation der Laufzeit aus dem C-Stack ermöglichen, anstatt vom Haufen (z. alloca ()[9]). Dieser Speicher wird automatisch befreit, wenn die Aufruffunktion endet.

Überblick über Funktionen

Die dynamischen Speicherzuweisungsfunktionen sind in definiert in stdlib.h Header (CSTDLIB Header in C ++).[1]

Funktion Beschreibung
malloc zuweist die angegebene Anzahl von Bytes
realloc Erhöht oder verringert die Größe des angegebenen Speicherblocks und bewegen Sie ihn bei Bedarf
calloc zuweist die angegebene Anzahl von Bytes und initialisiert sie auf Null
free Freisetzt den angegebenen Speicherblock zurück zum System

Unterschiede zwischen malloc () und CALLOC ()

  • malloc () nimmt ein einziges Argument (die Menge an Speicher, um Bytes zuzuweisen) während CALLOC () benötigt zwei Argumente (die Anzahl der Variablen, die im Speicher zuzuordnen sind, und die Größe in Bytes einer einzelnen Variablen).
  • malloc () initialisiert nicht den zugewiesenen Speicher, während CALLOC () Garantiert, dass alle Bytes des zugewiesenen Speicherblocks auf 0 initialisiert wurden.
  • Auf einigen Betriebssystemen, CALLOC () kann implementiert werden, indem zunächst alle Seiten der virtuellen Adressen des zugewiesenen Speichers auf eine schreibgeschützte Seite aller 0er und nur die physischen Seiten der Leseschreiber zugewiesen werden, wenn die virtuellen Adressen geschrieben werden, eine Methode namens namens Kopieren auf dem Schreiben.

Nutzungsbeispiel

An erstellen Array von zehn Ganzzahlen mit automatischem Umfang ist in C unkompliziert:

int Array[10]; 

Die Größe des Arrays ist jedoch zur Kompilierungszeit festgelegt. Wenn man ein ähnliches Array dynamisch zuweisen möchte, kann der folgende Code verwendet werden:

int *Array = Malloc(10 * Größe von(int)); 

Dies berechnet die Anzahl der Bytes, die zehn ganze Zahlen im Speicher einnehmen, und fordert dann an, dass viele Bytes von Malloc und weist a das Ergebnis einem zu Zeiger genannt Array (Aufgrund der C -Syntax können Zeiger und Arrays in einigen Situationen austauschbar verwendet werden).

Da Malloc Möglicherweise können Sie die Anfrage nicht bedienen, sondern möglicherweise a Null Zeiger Und es ist eine gute Programmierungspraxis, um dies zu überprüfen:

int *Array = Malloc(10 * Größe von(int)); wenn (Array == NULL) {   fprintf(Stderr, "Malloc ist gescheitert\n");   Rückkehr -1; } 

Wenn das Programm das nicht mehr braucht Dynamisches Array, es muss irgendwann anrufen frei Um den Speicher zurückzugeben, den er in den kostenlosen Laden einnimmt:

frei(Array); 

Der Speicher von vorgesehen von Malloc ist nicht initialisiert und kann enthalten Kräfte: Die Überreste zuvor verwendeter und verworfener Daten. Nach Zuteilung mit Malloc, Elemente des Arrays sind nicht initialisierte Variablen. Der Befehl CALLOC wird eine Zuweisung zurückgeben, die bereits gelöscht wurde:

int *Array = CALLOC(10, Größe von(int)); 

Mit Realloc können wir die Größe des Speichers ändern, auf den ein Zeiger zeigt. Zum Beispiel, wenn wir einen Zeiger haben, der als eine Reihe von Größe fungiert Und wir wollen es in eine Reihe von Größe ändern Wir können Realloc verwenden.

int *arr = Malloc(2 * Größe von(int)); arr[0] = 1; arr[1] = 2; arr = Realloc(arr, 3 * Größe von(int)); arr[2] = 3; 

Beachten Sie, dass Realloc angenommen werden muss, dass die Basisadresse des Blocks geändert wurde (d. H. Wenn er die Größe des ursprünglichen Blocks nicht erweitert und daher einen neuen größeren Block an anderer Stelle zugewiesen und den alten Inhalt kopiert hat). Daher sind auch alle Hinweise auf Adressen innerhalb des ursprünglichen Blocks nicht mehr gültig.

Geben Sie Sicherheit ein

Malloc Gibt eine zurück Hohlzeiger (Leere *), was angibt, dass es sich um einen Zeiger auf einen Bereich mit unbekanntem Datentyp handelt. Die Verwendung des Gießens ist in C ++ aufgrund des starken Typsystems erforderlich, während dies bei C nicht der Fall ist. Typumwandlung Typ) Dieser Zeiger auf einen bestimmten Typ:

int *ptr, *PTR2; ptr = Malloc(10 * Größe von(*ptr)); / * ohne Guss *// PTR2 = (int *)Malloc(10 * Größe von(*ptr)); / * mit einem Guss *// 

Die Durchführung einer solchen Besetzung haben Vor- und Nachteile.

Vorteile des Casting

  • Einschließlich des Casts kann ein C -Programm oder eine Funktion als C ++ ermöglichen.
  • Die Besetzung erlaubt es Versionen vor 1989 von Malloc Das hat ursprünglich a zurückgegeben char *.[10]
  • Casting kann dem Entwickler helfen, Inkonsistenzen in der Typgröße zu identifizieren, falls sich der Zielzeigertyp ändert, insbesondere wenn der Zeiger weit entfernt deklariert wird malloc () Rufen Sie an (obwohl moderne Compiler und statische Analysatoren vor diesem Verhalten warnen können, ohne die Besetzung zu verlangen[11]).

Nachteile zum Casting

  • Nach dem C -Standard ist die Besetzung überflüssig.
  • Das Hinzufügen des Gusss kann das Versagen des Headers maskieren stdlib.h, in dem die Funktionsprototyp zum Malloc gefunden.[10][12] In Ermangelung eines Prototyps für MallocDer C90 -Standard erfordert, dass der C -Compiler annimmt Malloc Gibt ein zurück int. Wenn es keine Besetzung gibt, benötigt C90 eine Diagnose, wenn diese Ganzzahl dem Zeiger zugeordnet ist. Mit der Besetzung würde diese Diagnose jedoch nicht erzeugt werden und versteckt einen Fehler. Auf bestimmten Architekturen und Datenmodellen (wie LP64 auf 64-Bit-Systemen, wo lang und Zeiger sind 64-Bit und int ist 32-Bit), dieser Fehler kann tatsächlich zu undefiniertem Verhalten führen, wie der implizit erklärt Malloc Gibt einen 32-Bit-Wert zurück, während die tatsächlich definierte Funktion einen 64-Bit-Wert zurückgibt. Abhängig vom Aufruf von Konventionen und Speicherlayout kann dies dazu führen Stapel zerschlagen. Dieses Problem ist in modernen Compilern weniger wahrscheinlich unbemerkt, da C99 keine impliziten Erklärungen zulässt int Rückkehr.
  • Wenn der Typ des Zeigers bei seiner Deklaration geändert wird, muss möglicherweise auch alle Zeilen wechseln, wo Malloc wird genannt und gegossen.

Häufige Fehler

Die unsachgemäße Verwendung der dynamischen Speicherzuweisung kann häufig eine Fehlerquelle sein. Diese können Sicherheitsfehler oder Programmabstürze umfassen, meistens aufgrund Segmentierungsfehler.

Die meisten häufigsten Fehler sind wie folgt:[13]

Nicht nach Zuteilungsfehlern überprüfen
Die Speicherzuweisung ist nicht garantiert erfolgreich und kann stattdessen einen Nullzeiger zurückgeben. Verwenden des zurückgegebenen Wertes, ohne zu überprüfen, ob die Zuweisung erfolgreich ist undefiniertes Verhalten. Dies führt normalerweise zu einem Absturz (aufgrund des resultierenden Segmentierungsfehlers am Nullzeiger Dereference), aber es gibt keine Garantie dafür, dass ein Absturz auftritt, sodass es auch zu Problemen führen kann.
Speicherlecks
Nichtverkleidungsverlagerung mit dem Speicher mithilfe frei führt zu einem Aufbau von nicht wiederverwendbarem Speicher, das vom Programm nicht mehr verwendet wird. Dies verschwendet Speicherressourcen und kann zu Allokationsfehlern führen, wenn diese Ressourcen erschöpft sind.
Logische Fehler
Alle Zuteilungen müssen dem gleichen Muster folgen: Zuordnung mit Verwendung Malloc, Nutzung zum Speichern von Daten, Deallokation mit frei. Fehler bei der Einhaltung dieses Musters, wie z. B. Speicherverbrauch nach einem Aufruf an frei (baumelnder Zeiger) oder vor einem Anruf an Malloc (Wild Zeiger), Berufung frei Zweimal ("doppelt frei") usw. verursacht normalerweise einen Segmentierungsfehler und führt zu einem Absturz des Programms. Diese Fehler können vorübergehend und schwer zu debuggen sein - zum Beispiel wird das befreite Gedächtnis normalerweise nicht sofort vom Betriebssystem zurückgefordert, und daher kann baumelnde Zeiger eine Weile bestehen und zu funktionieren.

Darüber hinaus als Schnittstelle, die der ANSI C -Standardisierung vorausgeht, malloc und seine damit verbundenen Funktionen haben Verhaltensweisen, die absichtlich der Implementierung überlassen wurden, um sie selbst zu definieren. Einer von ihnen ist die Zulassung von Nulllängen, die eher ein Problem mit realloc Da es häufiger ist, sich auf Null zu ändern.[14] Obwohl beides Posix und die Einzel -Unix -Spezifikation Erfordern Sie eine ordnungsgemäße Umführung von Zuteilungen von 0 Größe, indem Sie beider zurückkehren NULL oder etwas anderes, das sicher befreit werden kann,[15] Nicht alle Plattformen müssen diese Regeln einhalten. Unter den vielen doppeltfreien Fehlern, zu denen es geführt hat, die 2019 WhatsApp RCE war besonders prominent.[16] Eine Möglichkeit, diese Funktionen zu wickeln, um sie sicherer zu machen NULL hat seine eigenen Probleme: Ansonsten zeigt es einen außeremmory-Fehler an. Im Falle des realloc Es hätte signalisiert, dass der ursprüngliche Speicher nicht bewegt und befreit wurde, was wiederum bei Größe 0 nicht der Fall ist, was zum doppelfreien Free führt.)[17]

Implementierungen

Die Implementierung des Speichermanagements hängt stark vom Betriebssystem und der Architektur ab. Einige Betriebssysteme liefern einen Allocator für Malloc, während andere Funktionen liefern, um bestimmte Datenregionen zu steuern. Der gleiche dynamische Speicher Allocator wird häufig verwendet, um beide zu implementieren Malloc und der Bediener Neu in C ++.[18]

Haufensbasiert

Die Implementierung des Allocators erfolgt häufig mit dem Haufen, oder Datensegment. Der Allocator erweitert in der Regel den Haufen, um Allokationsanfragen zu erfüllen.

Die Heap -Methode leidet an einigen inhärenten Mängel Zersplitterung. Wie jede Methode zur Speicherzuweisung wird der Haufen fragmentiert; Das heißt, es gibt Abschnitte des gebrauchten und nicht verwendeten Speichers im zugewiesenen Raum auf dem Haufen. Ein guter Allokator wird versuchen, einen ungenutzten Bereich bereits zugewiesener Speicher zu finden, der vor dem Ausbau des Haufens verwendet wird. Das Hauptproblem bei dieser Methode besteht darin, dass der Haufen nur zwei signifikante Attribute hat: Basis oder den Beginn des Haufens im virtuellen Speicherplatz; und Länge oder seine Größe. Der Haufen erfordert genug Systemspeicher, um seine gesamte Länge zu füllen, und seine Basis kann sich nie ändern. Somit werden große Bereiche des ungenutzten Gedächtnisses verschwendet. Der Haufen kann in dieser Position "stecken" werden, wenn am Ende des Haufens ein kleines gebrauchtes Segment vorhanden ist, was jede Menge Adressraum verschwenden könnte. Bei faulen Speicherzuweisungsschemata, wie sie häufig im Linux -Betriebssystem enthalten sind, behält sich ein großer Haufen nicht unbedingt den äquivalenten Systemspeicher vor. Dies wird dies nur zum ersten Schreibzeit haben (Lesungen von nicht eingebauten Speicherseiten geben Null zurück). Die Granularität davon hängt von der Seitengröße ab.

Dlmalloc und ptmalloc

Doug Lea hat die entwickelt öffentlich zugänglich Dlmalloc ("Doug Lea's Malloc") als allgemeiner Allocator, ab 1987. Die GNU C -Bibliothek (GLIBC) stammt aus Wolfram Glogers PtMalloc ("pthreads malloc"), einer Gabel von dlmalloc mit Fadenverbesserungen.[19][20][21] Ab November 2019 ist die neueste Version von DlMalloc vom August 2012 Version 2.8.6.[22]

DlMalloc ist ein Grenz -Tag -Allocator. Speicher auf der Haufen wird als "Stücke" zugeordnet, eine 8-Byte ausgerichtet Datenstruktur die einen Kopfball und ein nutzbares Gedächtnis enthält. Zugegebener Speicher enthält einen 8- oder 16-Byte Dope -Vektor). Nicht zugewiesene Stücke speichern auch Hinweise auf andere freie Stücke im nutzbaren Raumbereich, sodass die Mindestbytes von 16 Bytes auf 32-Bit-Systemen und 24/32 (abhängig von der Ausrichtung) Bytes auf 64-Bit-Systemen.[20][22]: 2.8.6, minimal zugewiesene Größe

Das nicht zugewiesene Gedächtnis wird in "gruppiert"Mülleimer"von ähnlichen Größen, implementiert unter Verwendung einer doppelt verknüpften Liste von Stücken (mit Zeigern, die im nicht zugewiesenen Raum im Stadtraum gespeichert sind). Behälter werden nach Größe in drei Klassen sortiert:[20][22]: Überlagte Datenstrukturen

  • Für Anfragen unter 256 Bytes (eine "SmallBin" -Anforderung) wird ein einfacher Allocator für zwei Leistungsträger verwendet. Wenn sich in diesem Behälter keine freien Blöcke befinden, ist ein Block vom nächsthöheren Behälter in zwei Teile geteilt.
  • Für Anfragen von 256 Bytes oder höher, jedoch unter dem MMAP Schwelle, dlmalloc seit v2.8.0 Verwendung ein Ort Bitwise Trie Algorithmus ("Treebin"). Wenn es keinen freien Speicherplatz gibt, um die Anfrage zu erfüllen, versucht DlMalloc, die Größe des Haufens zu erhöhen, normalerweise über die BRK Systemanruf. Diese Funktion wurde nach dem Erstellen von PtMAlloc (aus V2.7.x) eingeführt, und infolgedessen ist kein Teil von GLIBC, was den alten Best-fit-Allocator erbt.
  • Für Anfragen über dem MMAP -Schwellenwert (eine "LargeBin" -Anforderung) wird der Speicher immer mit dem Speicher zugewiesen MMAP Systemanruf. Der Schwellenwert beträgt normalerweise 256 kb.[23] Die MMAP -Methode wendet Probleme mit riesigen Puffern ab, die am Ende nach ihrem Ablauf eine kleine Zuordnung einfangen, verteilt aber immer eine ganze Seite des Gedächtnisses, der auf vielen Architekturen 4096 Bytes groß ist.[24]

Spielentwickler Adrian Stone argumentiert das dlmalloc, als Grenzmarkallocator ist unfreundlich für Konsolensysteme, die einen virtuellen Gedächtnis haben, aber nicht haben Paging fordern. Dies liegt daran, dass seine Pool-Shrink- und Wachstumsrückrufe (Sysmalloc/Systrim) nicht verwendet werden können, um einzelne Seiten des virtuellen Gedächtnisses zuzuweisen und zu begehen. In Ermangelung von Nachfrage -Paging wird die Fragmentierung zu einem größeren Anliegen.[25]

Jemalloc von FreeBSD und NetBsd

Seit Freebsd 7.0 und Netbsd 5.0 das alte Malloc Implementierung (Phkmalloc von Poul-Henning Kamp) wurde durch ersetzt durch Jemalloc, geschrieben von Jason Evans. Der Hauptgrund dafür war ein Mangel an Skalierbarkeit von Phkmalloc in Bezug auf Multithreading. Um die Konkurrenz von Sperrungen zu vermeiden, verwendet Jemalloc für jeden separaten "Arenen" Zentralprozessor. Experimente zur Messung der Anzahl der Zuordnungen pro Sekunde in der Multithreading -Anwendung haben gezeigt, dass dies linear mit der Anzahl der Threads skaliert wird, während sowohl für phkmalloc- als auch für dlmalloc -Leistung umgekehrt proportional zur Anzahl der Threads war.[26]

OpenBSDs Malloc

OpenBSDImplementierung der Malloc Funktion benutzt von MMAP. Für Anfragen größerer Größe als eine Seite wird die gesamte Zuweisung verwendet MMAP; Kleinere Größen werden aus Speicherpools zugewiesen, die von gepflegt werden von Malloc Innerhalb einer Reihe von "Bucket -Seiten", die ebenfalls zugewiesen wurden MMAP.[27] Auf einen Anruf bei frei, der Speicher wird vom Prozess freigegeben und entkundet Adressraum Verwendung Munmap. Dieses System soll die Sicherheit verbessern, indem sie die ausnutzen Adressraumlayout Randomisierung und Gap -Seitenfunktionen, die im Rahmen von OpenBSDs implementiert sind MMAP Systemanrufund um nutzungsfreie Fehler zu erkennen-wie eine große Speicherzuweisung vollständig nicht kartiert wird, nachdem sie befreit wurde, verursacht weiter die Verwendung a Segmentierungsfehler und Beendigung des Programms.

Horten Malloc

Hoard ist ein Allocator, dessen Ziel skalierbare Speicherzuweisungsleistung ist. Wie OpenBSDs Allocator verwendet Hoard MMAP Exklusiv, aber das Gedächtnis in Stücken von 64 Kilobyten namens Superblocks verwaltet. Der Haufen des Hoards ist logischerweise in einen einzigen globalen Haufen und eine Reihe von pro Prozessorhaufen unterteilt. Darüber hinaus gibt es einen Thread-lokalen Cache, der eine begrenzte Anzahl von Superblocks enthalten kann. Durch die Zuweisung von Superblocks auf dem lokalen Haufen pro Thread oder pro Prozessor und der Überstellung von Superblöcken auf den globalen Haufen, damit sie von anderen Prozessoren wiederverwendet werden können, hält Horte die Fragmentierung niedrig und erreicht gleichzeitig die nahe lineare Skalierbarkeit mit der Anzahl der Fäden .[28]

Mimalloc

Ein Open Source Kompakte Allgemeinzwecke Speicherallocator aus Microsoft Research mit Fokus auf Leistung.[29] Die Bibliothek ist ungefähr 11.000 Zeilen von Code.

Thread-Mallloc (TcMalloc)

Jeder Thread hat eine Thread-lokaler Speicher Für kleine Zuteilungen. Für große Zuordnungen mmap oder SBRK kann verwendet werden. TcMalloc, a Malloc entwickelt von Google,[30] hat Müllsammlung für die lokale Lagerung von toten Fäden. Das TCMALLOC wird als doppelt so schnell angesehen wie das PtMalloc von Glibc für Multithread -Programme.[31][32]

Dfwmalloc

Eine hochkonfigurierbare Malloc-Bibliothek mit lock-freier Funktionalität, Dfwmalloc Es ist so konzipiert, dass Unternehmensumgebungen gegenüber der Fragmentierung robust sind und die Laufzeitprüfung des Allokationsraums ermöglichen.

In-Kernel

Betriebssystem Kerne Müssen Speicher genauso wie Anwendungsprogramme zuweisen. Die Implementierung von Malloc Innerhalb eines Kernels unterscheidet sich jedoch häufig erheblich von den von C -Bibliotheken verwendeten Implementierungen. Zum Beispiel müssen Speicherpuffer möglicherweise den speziellen Einschränkungen entsprechen, die von auferlegt werden können DMAoder die Speicherzuweisungsfunktion kann aus dem Interrupt -Kontext aufgerufen werden.[33] Dies erfordert a Malloc Implementierung eng integriert in die virtueller Speicher Subsystem des Betriebssystemkerns.

Übergeordnetes Malloc

Da Malloc Und seine Verwandten können starke Auswirkungen auf die Leistung eines Programms haben. Es ist nicht ungewöhnlich, die Funktionen für eine bestimmte Anwendung durch benutzerdefinierte Implementierungen zu überschreiben, die für die Zuordnungsmuster der Anwendungen optimiert sind. Der C -Standard bietet keine Möglichkeit, dies zu tun, aber Betriebssysteme haben verschiedene Möglichkeiten gefunden, dies zu tun, indem dynamische Verknüpfungen ausgenutzt werden. Eine Möglichkeit besteht darin, einfach in einer anderen Bibliothek zu verknüpfen, um die Symbole zu überschreiben. Eine andere, angestellt bei UNIX -System V.3, Ist zu machen Malloc und frei Funktionszeiger, die eine Anwendung auf benutzerdefinierte Funktionen zurücksetzen kann.[34]

Zuteilungsgrößengrenzen

Der größtmögliche Speicherblock Malloc Die Zuordnung von Can zutreffen hängt vom Host -System ab, insbesondere von der Größe des physischen Speichers und der Implementierung des Betriebssystems.

Theoretisch sollte die größte Zahl der Höchstwert sein, der in a gehalten werden kann size_t Typ, eine implementierungsabhängige nicht signierte Ganzzahl, die die Größe eines Speicherbereichs darstellt. In dem C99 Standard und später ist es als die erhältlich Size_max konstant von . Obwohl nicht garantiert von ISO c, das ist normal 2^(char_bit * sizeof (size_t)) - 1.

Auf GLIBC -Systemen der größtmögliche Speicherblock Malloc kann zuweisen, ist nur halb so groß, nämlich nämlich 2^(char_bit * sizeof (ptrdiff_t) - 1) - 1.[35]

Erweiterungen und Alternativen

Die C -Bibliotheksimplementierungen Versand mit verschiedenen Betriebssystemen und Compilern können Alternativen und Erweiterungen zum Standard ausführen Malloc Schnittstelle. Bemerkenswert unter diesen ist:

  • Alloca, was eine angeforderte Anzahl von Bytes auf dem zuweist Rufen Sie Stack an. Es gibt keine entsprechende DealLocationsfunktion, da der Speicher typischerweise verhandelt wird, sobald die Aufruffunktion zurückgibt. Alloca war schon auf UNIX -Systemen vorhanden 32/v (1978), aber seine Verwendung kann in einigen (z. B. eingebetteten) Kontexten problematisch sein.[36] Während es von vielen Compilern unterstützt wird, ist es nicht Teil der ANSI-C Standard und ist daher möglicherweise nicht immer tragbar. Es kann auch zu geringfügigen Leistungsproblemen führen: Es führt zu Stapelrahmen variabler Größe, so dass beide Stapel- und Rahmenzeiger müssen verwaltet werden (mit Stapelrahmen mit fester Größe ist eine davon überflüssig).[37] Größere Zuordnungen können auch das Risiko eines undefinierten Verhaltens durch a erhöhen Paketüberfluss.[38] C99 angeboten Arrays variabler Länge Als alternativer Stack -Allokation -Mechanismus wurde diese Funktion jedoch in später auf optional abgestiegen C11 Standard.
  • Posix definiert eine Funktion pox_memalign Das verteilt den Speicher mit Anrufer-spezifizierter Ausrichtung. Seine Zuteilungen werden mit behandelt frei,[39] Die Implementierung muss also normalerweise Teil der Malloc -Bibliothek sein.

Siehe auch

Verweise

  1. ^ a b 7.20.3 Speicherverwaltungsfunktionen (PDF). ISO/IEC 9899: 1999 Spezifikation. p. 313.
  2. ^ Summit, Steve. "Kapitel 11: Speicherzuweisung". C Programmiernoten. Abgerufen 2020-07-11.
  3. ^ Stroustrup, Bjarne (2008). Programmierung: Prinzipien und Praxis mit C ++. Addison Wesley. p. 1009. ISBN 978-0-321-54372-1.
  4. ^ "GCC -Handbuch". gnu.org. Abgerufen 2008-12-14.
  5. ^ Brian W. Kernighan, Dennis M. Ritchie, Die C -Programmiersprache, Prentice-Hall, 1978; Abschnitt 7.9 (Seite 156) beschreibt CALLOC und cfreeund Abschnitt 8.7 (Seite 173) beschreibt eine Implementierung für Alloc und frei.
  6. ^ Alloc (3)- -Version 6 Unix Programmierer Handbuch
  7. ^ Malloc (3)- -Version 7 Unix Programmierer Handbuch
  8. ^ Anonym, UNIX Programmer's Manual, Vol. 1Holt Rinehart und Winston, 1983 (Copyright von Bell Telefonlabors, 1983, 1979); Das Mann Seite für Malloc usw. wird auf Seite 275 angegeben.
  9. ^ Alloca (3)- -Freebsd Bibliotheksfunktionen Handbuch
  10. ^ a b "Malloc Casting". Cprogramming.com. Abgerufen 2007-03-09.
  11. ^ "Clang: lib/staticanalyzer/Checkers/mallocsizeofChecker.cpp Quelldatei". Clang.llvm.org. Abgerufen 2018-04-01.
  12. ^ "comp.lang.c FAQ -Liste · Frage 7.7b". C-Faq. Abgerufen 2007-03-09.
  13. ^ Reek, Kenneth (1997-08-04). Zeiger auf c (1 ed.). Pearson. ISBN 9780673999863.
  14. ^ "MEM04 -C. Vorsicht von Zullierungszuweisungen - SEI -Zertifikat C -Codierungsstandard - Konfluenz". Wiki.Sei.cmu.edu.
  15. ^ "POSIX.1-2017: Malloc". Pubs.opengroup.org. Abgerufen 2019-11-29.
  16. ^ Awakened (2019-10-02). "Wie sich ein doppeltfreier Fehler in WhatsApp zu RCE dreht". Abgerufen 2019-11-29.
  17. ^ Felker, Rich (2019-10-03). "Wow. Das WhatsApp -RCE war das falsche Verhalten für Realloc (p, 0) So viele Implementierungen bestehen auf.https: //twitter.com/ottom6k/status/1179623539726524417 ...". Twitter. Abgerufen 2019-11-29. {{}}: Externer Link in |title= (Hilfe)
  18. ^ Alexandrescu, Andrei (2001). Modernes C ++ - Design: Generische Programmier- und Entwurfsmuster angewendet. Addison-Wesley. p. 78.
  19. ^ "Wolfram Glogers Malloc -Homepage". malloc.de. Abgerufen 2018-04-01.
  20. ^ a b c Kaempf, Michel (2001). "Vudo Malloc Tricks". Phrack (57): 8. Archiviert vom Original am 2009-01-22. Abgerufen 2009-04-29.
  21. ^ "GLIBC: Malloc -Interna". Sourceware.org Trac. Abgerufen 2019-12-01.
  22. ^ a b c Lee, Doug. "Ein Speicherallocator". Abgerufen 2019-12-01. HTTP für Quellcode
  23. ^ "Malloc -Abstimmungsparameter". GNU. Abgerufen 2009-05-02.
  24. ^ Sanderson, Bruce (2004-12-12). "RAM, virtueller Speicher, Pagefile und all das Zeug". Microsoft Hilfe und Support.
  25. ^ Stein, Adrian. "Das Loch, das dlmalloc nicht füllen kann". Spielestest. Abgerufen 2019-12-01.
  26. ^ Evans, Jason (2006-04-16). "Eine skalierbare gleichzeitige Malloc -Implementierung für FreeBSD" (PDF). Abgerufen 2012-03-18.
  27. ^ "libc/stdlib/malloc.c". BSD Cross Referenz, OpenBSD SRC/lib/.
  28. ^ Berger, E. D.; McKinley, K. S.; Blumofe, R. D.; Wilson, P. R. (November 2000). Hort (PDF). Asplos-X. Verfahren der neunten internationalen Konferenz über architektonische Unterstützung für Programmiersprachen und Betriebssysteme. S. 117–128. Citeseerx 10.1.1.1.4174. doi:10.1145/378993.379232. ISBN 1-58113-317-0.
  29. ^ Microsoft veröffentlicht optimierte malloc () als Open Source - Slashdot
  30. ^ TcMalloc homepage
  31. ^ Ghemawat, Sanjay; Menage, Paul; TcMalloc: Thread-Mallloc-Mallloc
  32. ^ Callaghan, Mark (2009-01-18). "Hohe Verfügbarkeit MySQL: Doppel -Sysbench -Durchsatz mit tcMalloc". Mysqlha.blogspot.com. Abgerufen 2011-09-18.
  33. ^ "kmalloc ()/kfree () include/linux/slab.h". People.netfilter.org. Abgerufen 2011-09-18.
  34. ^ Levine, John R. (2000) [Oktober 1999]. "Kapitel 9: gemeinsame Bibliotheken". Linker und Lader. Die Morgan Kaufmann -Serie in Software Engineering and Programming (1 Ed.). San Francisco, USA: Morgan Kaufmann. ISBN 1-55860-496-0. OCLC 42413382. Archiviert vom Original am 2012-12-05. Abgerufen 2020-01-12. Code: [1][2] Errata: [3]
  35. ^ "Malloc: Malloc scheitern mit Anfragen, die größer als pTRDIFF_MAX sind". Sourceware Bugzilla. 2019-04-18. Abgerufen 2020-07-30.
  36. ^ "Warum wird die Verwendung von Alloca () nicht als gute Praxis angesehen?". stackoverflow.com. Abgerufen 2016-01-05.
  37. ^ Amarasinghe, Saman; Leiserson, Charles (2010). "6.172 Performance Engineering von Softwaresystemen, Vortrag 10". MIT openCourseware. Massachusetts Institute of Technology. Archiviert von das Original Am 2015-06-22. Abgerufen 2015-01-27.
  38. ^ "Alloca (3) - Linux Manual Page". Man7.org. Abgerufen 2016-01-05.
  39. ^ pox_memalign- Systemoberflächenreferenz, Die einzelne Unix -Spezifikation, Version 4 von Die offene Gruppe

Externe Links