malloc(3)

BEZEICHNUNG
malloc, free, calloc, realloc, reallocarray - dynamischen Speicher belegen und freigeben

BIBLIOTHEK
Standard-C-Bibliothek (libc, -lc)

ÜBERSICHT
#include <stdlib.h>

void *malloc(size_t Größe);
void free(void *_Nullable z);
void *calloc(size_t n, size_t Größe);
void *realloc(void *_Nullable z, size_t Größe);
void *reallocarray(void *_Nullable z, size_t n, size_t Größe);

    Mit Glibc erforderliche Feature-Test-Makros (siehe feature_test_macros(7)):

reallocarray():
    Seit Glibc 2.29:
        _DEFAULT_SOURCE
    Glibc 2.28 und älter:
        _GNU_SOURCE

BESCHREIBUNG

  malloc()
Die Funktion malloc() belegt Größe Byte und gibt einen Zeiger auf den belegten Speicherbereich zurück. Der Speicher wird nicht initialisiert. Falls Größe 0 ist, wird malloc() einen eindeutigen Zeigerwert zurückgeben, der später erfolgreich an free() übergeben werden kann. (Siehe »Nichtportables Verhalten« für Portabilitäts-Probleme.)

  free()
free() gibt den Speicher frei, auf den z zeigt, welcher von einem früheren Aufruf von malloc() oder verwandten Funktionen belegt worden sein muss. Andernfalls oder wenn z bereits freigegeben wurde, ist das Verhalten nicht definiert. Wenn z NULL ist, wird keine Operation ausgeführt.

  calloc()
Die Funktion calloc() belegt Speicher für ein Feld von n Elementen der jeweiligen Größe Größe und liefert einen Zeiger auf den belegten Speicher zurück. Der Speicher wird auf 0 gesetzt. Falls n oder Größe 0 ist, wird calloc() einen eindeutigen Zeigerwert zurückgeben, der später erfolgreich an free() übergeben werden kann.

Falls die Multiplikation von n und Größe zu einem Ganzzahlüberlauf führen würde, dann liefert calloc() einen Fehler zurück. Im Gegensatz dazu würde ein Ganzzahlüberlauf in dem nachfolgenden Aufruf von malloc() nicht erkannt werden, was zu einer Zuweisung eines Speicherblocks mit falscher Größe führen würde:

    malloc(n * Größe);

  realloc()
realloc() ändert die Größe des Speicherblocks, auf den z zeigt, auf Größe Byte. Der Inhalt des Speichers bleibt im Bereich vom Anfang des Speicherbereichs bis zum Minimum von alter und neuer Größe unverändert. Falls die neue Größe die alte überschreitet, wird der zusätzliche Speicher nicht initialisiert.

Falls z gleich NULL ist, ist der Aufruf äquivalent zu malloc(Größe).

falls die Größe gleich Null und z von NULL verschieden ist, ist der Aufruf äquivalent zu free(z) (siehe aber »Nichtportables Verhalten« für Portabilitäts-Probleme.)

Wenn z nicht NULL ist, muss er von einem früheren Aufruf von malloc() oder verwandten Funktionen zurückgegeben worden sein. Falls der Bereich, auf den verwiesen wurde, verschoben wurde, wird free(z) aufgerufen.

  reallocarray()
Die Funktion reallocarray() ändert die Größe des Speicherblocks, auf den z zeigt, (und verschiebt ihn möglicherweise,) damit er groß genug für ein Feld von n Elementen mit jeweils Größe Byte ist. Sie ist äquivalent zu dem Aufruf:

    realloc(z, n * Größe);

Allerdings schlägt reallocarray(), anders als obiger Aufruf von realloc(), sicher fehl, wenn die Multiplikation überliefe. Falls solch ein Überlauf auftritt, liefert reallocarray() einen Fehler zurück.

RÜCKGABEWERT
Die Funktionen malloc(), calloc(), realloc() und reallocarray() liefern einen Zeiger auf den reservierten Speicher, der geeignet für jeden Typ, der in die angeforderte Größe oder weniger passt, ausgerichtet ist. Tritt ein Fehler auf, geben diese Funktionen NULL zurück und setzen errno. Versuche, mehr als PTRDIFF_MAX byte zu belegen, wird als ein Fehler betrachtet, da ein Objekt dieser Größe bei späterer Zeigersubtraktion zu einem Überlauf führen könnte.

Die Funktion free() gibt keinen Wert zurück und erhält errno.

Die Funktionen realloc() und reallocarray() liefern NULL zurück, falls z nicht NULL ist und die angeforderte Größe Null ist; dies wird nicht als Fehler betrachtet. (Siehe »Nichtportables Verhalten« für Portabilitäts-Probleme.) Andernfalls kann der zurückgelieferte Zeiger zu z identisch sein, falls die Belegung nicht verschoben wurde (z.B. weil genug Platz vorhanden war, um die Belegung am Ort selbst zu vergrößern) oder sich von z unterscheiden, falls die Belegung an eine neue Adresse verschoben wurde. Wenn diese Funktionen scheitern, bleibt der ursprüngliche Block unverändert - er wird nicht freigegeben oder verschoben.

FEHLER
calloc(), malloc(), realloc() und reallocarray() können mit den folgenden Fehlern fehlschlagen:

ENOMEM
    Speicher erschöpft. Möglicherweise erreichte die Anwendung die in getrlimit(2) beschriebene Grenze RLIMIT_AS oder RLIMIT_DATA. Ein anderer Grund könnte sein, dass die Anzahl der durch den aufrufenden Prozess erstellten Mappings die durch /proc/sys/vm/max_map_count festgelegte Grenze überschritten hat.

ATTRIBUTE
Siehe attributes(7) für eine Erläuterung der in diesem Abschnitt verwandten Ausdrücke.
Schnittstelle | Attribut | Wert
malloc(), free(), calloc(), realloc() | Multithread-Fähigkeit | MT-Sicher

STANDARDS

malloc()
free()
calloc()
realloc()
    C23, POSIX.1-2024.

reallocarray()
    POSIX.1-2024.

  realloc(p, 0)
Das Verhalten von realloc(p, 0) in Glibc ist weder zu C99, C11, POSIX.1-2001, POSIX.1-2004, POSIX.1-2008, POSIX.1-2013, POSIX.1-2017, noch POSIX.1-2024 konform. Die C17-Spezifikation wurde geändert, damit sie konform wurde, aber diese Spezifikation machte es unmöglich Code zu schreiben, der zuverlässig bestimmt, ob der Eingabezeiger nach realloc(p, 0) freigegeben wurde und C23 änderte es wieder, um dies als undefiniertes Verhalten festzulegen. Damit wurde zugegeben, dass die C17-Spezifikation allgemein genug war, so dass das undefinierte Verhalten nicht schlechter als das war.

reallocarray() leidet unter den gleichen Problemen in Glibc.

Musl Libc und die BSDs sind zu allen Versionen von ISO C und POSIX.1 konform.

Glibc stellt das Modul realloc-posix bereit, das die Wrapper realloc() und reallocarray() bereitstellt, die zu allen Versionen von ISO C und POSIX.1 konform sind.

Es gibt einen Vorschlag, das BSD-Verhalten zu normen: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3621.txt.

GESCHICHTE

malloc()
free()
calloc()
realloc()
    POSIX.1-2001, C89.

reallocarray()
    Glibc 2.26. OpenBSD 5.6, FreeBSD 11.0.

malloc() und verwandte Funktionen lehnen seit Glibc 2.30 Größen größer als PTRDIFF_MAX ab.

Seit Glibc 2.33 erhält free() errno.

  realloc(p, 0)
C89 war in seiner Spezifikation von realloc(p, 0) mehrdeutig. C99 behob dies teilweise.

Die ursprüngliche Implementierung in Glibc wäre konform zu C99 gewesen. Ironischerweise wurde allerdings versucht, C99 einzuhalten, bevor die Norm veröffentlicht wurde und so änderte Glibc 2.1.1 sein Verhalten derart, dass es nicht mehr zu der veröffentlichten Fassung der C99-Spezifikation konform war (dies ist allerdings umstritten, da die Formulierung der Norm sich selbst zu widersprechen scheint).

ANMERKUNGEN
Standardmäßig verfolgt Linux eine optimistische Strategie bei der Speicherzuweisung. Das bedeutet nicht, dass der Speicher garantiert verfügbar ist, wenn malloc() einen von NULL verschiedenen Zeiger zurück gibt. Falls es sich herausstellt, dass das System über keinen freien Speicher verfügt, werden ein oder mehrere Prozesse vom OOM-Killer getötet. Für weitere Informationen siehe die Beschreibung von /proc/sys/vm/overcommit_memory und /proc/sys/vm/oom_adj in proc(5) sowie die Linux-Kernel-Quelldatei Documentation/vm/overcommit-accounting.rst.

Normalerweise stellt malloc() Speicher auf dem Heap bereit und passt je nach Bedarf die Größe des Heaps mittels sbrk(2) an. Bei der Zuweisung von Speicherblöcken größer als MMAP_THRESHOLD Bytes reserviert die Glibc-Implementierung von malloc() mithilfe von mmap(2) den Speicher als ein privates anonymes Mapping. MMAP_THRESHOLD ist standardmäßig 128 kB, kann aber mittels mallopt(3) angepasst werden. Vor Linux 4.7 waren Reservierungen unter Verwendung von mmap(2) von der Ressourcenbeschränkung RLIMIT_DATA nicht betroffen; seit Linux 4.7 wird diese Beschränkung auch bei Reservierungen mittels mmap(2) durchgesetzt.

Um Verfälschungen in Multithread-Anwendungen zu vermeiden, werden intern Mutexe zum Schutz der Speicherverwaltungs-Datenstrukturen eingesetzt, die von diesen Funktionen genutzt werden. In einer Multithread-Anwendung, in denen Threads gleichzeitig Speicher zuweisen und freigeben, könnte es Zugangskonflikte für diese Mutexe geben. Um die Speicherzuweisung in Multithread-Anwendungen skalierbar zu bewältigen, erzeugt Glibc zusätzliche memory allocation arenas, wenn Mutex-Konflikte entdeckt wird. Jede Arena ist eine große Speicherregion, die intern vom System (mit brk(2) oder mmap(2)) zugeordnet und mit eigenen Mutexen verwaltet wird.

Falls Ihr Programm einen privaten Speicher-Zuordner verwendet, sollte dies so erfolgen, dass malloc(), free(), calloc() und realloc() ersetzt werden. Die Ersatzfunktionen müssen das dokumentierte Glibc-Verhalten implementieren, einschließlich der Handhabung von errno, Belegungen der Größe Null und der Prüfungen auf Überlauf; andernfalls könnten andere Bibliotheksroutinen abstürzen oder falsch funktionieren. Falls der Ersatz für free() beispielsweise errno nicht erhält, dann könnten Bibliotheksfunktionen, die scheinbar keinen Bezug dazu haben, fehlschlagen, ohne einen gültigen Grund in errno anzugeben. Private Speicher-Zuordner könnten es auch notwendig machen, andere Glibc-Funktionen zu ersetzen; siehe »Replacing malloc« im Handbuch der Glibc für Details.

Abstürze in Speicher-Zuordner haben nahezu immer einen Bezug zu einem beschädigten Heap, wie z.B. eine Nutzung von mehr als dem zugeordneten Bereich (overflowing) oder die doppelte Freigabe eines Zeigers.

Die malloc()-Implementierung kann über Umgebungsvariablen eingestellt werden. Für Details siehe mallopt(3).

  Nichtportierbares Verhalten
Das Verhalten dieser Funktionen, wenn die angeforderte Größe Null ist, ist Glibc-spezifisch; andere Implementierungen könnten NULL zurückliefern ohne errno zu setzen. Portierbare POSIX-Programme sollten solches Verhalten zulassen. Siehe realloc(3p).

POSIX verlangt von Speicher-Zuordnern, dass sie beim Fehlschlag errno setzten. Allerdings verlangt der C-Standard dies nicht und Anwendungen, die auf nicht-POSIX-Plattformen portierbar sein sollen, sollten dies nicht voraussetzen.

Portierbare Programme sollten keine privaten Speicher-Zuordner verwenden, da POSIX und der C-Standard keinen Ersatz für malloc(), free(), calloc() und realloc() erlauben.

FEHLER
Programmierer würden gemäß Induktion natürlicherweise erwarten, dass realloc(p, size) mit free(p) und malloc(size) konsistent ist, da dies das Verhalten in dem allgemeinen Falle ist. Dies wird von POSIX.1-2024 oder C11 nicht explizit verlangt, aber alle konformen Implementierungen sind damit konsistent.

Die Glibc-Implementierung von realloc() ist damit nicht konsistent und konsequenterweise ist es daher gefährlich, realloc(p, 0) in Glibc aufzurufen.

In Glibc kann dies trivial durch Aufruf von realloc(p, size?size:1) umgangen werden.

Die Vermeidung für reallocarray() in Glibc –das dem gleichen Fehler unterliegt– wäre reallocarray(p, n?n:1, size?size:1).

BEISPIELE
    #include <err.h>
    #include <stddef.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    #define MALLOCARRAY(n, type)  ((type *) my_mallocarray(n, sizeof(type)))
    #define MALLOC(type)          MALLOCARRAY(1, type)

    static inline void *my_mallocarray(size_t n, size_t size);

    int
    main(void)
    {
        char  *p;

        p = MALLOCARRAY(32, char);
        if (p == NULL)
            err(EXIT_FAILURE, "malloc");

        strlcpy(p, "foo", 32);
        puts(p);
    }

    static inline void *
    my_mallocarray(size_t n, size_t size)
    {
        return reallocarray(NULL, n, size);
    }

SIEHE AUCH
valgrind(1), brk(2), mmap(2), alloca(3), malloc_get_state(3), malloc_info(3), malloc_trim(3), malloc_usable_size(3), mallopt(3), mcheck(3), mtrace(3), posix_memalign(3)

Für Details über die GNU-C-Bibliotheksimplementierung, siehe https://sourceware.org/glibc/wiki/MallocInternals.

ÜBERSETZUNG
Die deutsche Übersetzung dieser Handbuchseite wurde von Martin Eberhard Schauer <Martin.E.Schauer@gmx.de>, Mario Blättermann <mario.blaettermann@gmail.com> und Helge Kreutzmann <debian@helgefjell.de> erstellt.

Diese Übersetzung ist Freie Dokumentation; lesen Sie die GNU General Public License Version 3 (https://www.gnu.org/licenses/gpl-3.0.html) oder neuer bezüglich der Copyright-Bedingungen. Es wird KEINE HAFTUNG übernommen.

Wenn Sie Fehler in der Übersetzung dieser Handbuchseite finden, schicken Sie bitte eine E-Mail an die Mailingliste der Übersetzer: debian-l10n-german@lists.debian.org.