malloc(3)

NAAM
malloc, free, calloc, realloc - reserveren en vrijmaken van dynamisch geheugen

BIBLIOTHEEK
Standard C bibliotheek (libc, -lc)

SAMENVATTING
#include <stdlib.h>

void *malloc(size_t size);
void free(void *_Nullable ptr);
void *calloc(size_t nmemb, size_t size);
void *realloc(void *_Nullable ptr, size_t size);
void *reallocarray(void *_Nullable ptr, size_t nmemb, size_t size);

    Feature Test Macro´s eisen in glibc (zie feature_test_macros(7)):

reallocarray():
    Sinds glibc 2.29:
        _DEFAULT_SOURCE
    Glibc 2.28 en eerder:
        _GNU_SOURCE

BESCHRIJVING

  malloc()
De malloc() functie reserveert grootte bytes geheugen en geeft een wijzer naar het gereserveerde geheugen terug. Het geheugen wordt niet geinitialiseerd. Als grootte gelijk is aan 0, dan retourneert malloc() een unieke wijzer waarde die later kan worden mee gegeven aan free(). (Zie "Niet overdraagbaar gebrag" voor overdraagbaarheids onderwerpen)

  free()
De free() functie geeft de geheugen-ruimte waar wzr naar wijst vrij, geheugen dat gereserveerd moet zijn door een eerdere aanroep naar malloc() of gerelateerde functies. Anders, of als free(wzr) al eerder werd aangeroepen, ontstaat onbepaald gedrag. Als wzr NULL is wordt niets gedaan.

  calloc()
De calloc() functie reserveert grootte bytes geheugen en geeft een wijzer naar het gereserveerde geheugen terug. Het geheugen wordt met nul geïnitialiseerd. Als nmemb of grootte gelijk is aan 0, dan retourneert calloc() een unieke wijzer waarde die later succesvol kan worden mee gegeven aan free().

Als de multiplicatie van nmemb en grootte zou resulteren in het overlopen van een geheel getal, dan geeft calloc() een fout terug. In tegenstelling daarmee, zou het overlopen van een geheel getal niet gedetecteerd worden in de volgende aanroep van malloc(), met als resultaat dat een geheugen blok van niet correct grootte zou worden toegewezen:

    malloc(nmemb * grootte);

  realloc()
De realloc() functie verandert de grootte van het geheugen-blok waar wzr naar wijst in grootte bytes. De inhoud zal onveranderd blijven in het gebied dat begint bij het geheugen gebied tot aan het minimum van de oude en nieuwe grootte. Als de nieuwe grootte groter is dan de oude dan wordt het toegevoegde geheugen niet geïnitialiseerd.

Als wzr NULL is, dan is de aanroep equivalent aan malloc(grootte), voor alle waarden van grootte.

Als grootte gelijk is aan nul, en wzr is niet NULL, dan is de aanroep equivalent aan free(ptr) (echter zie "Niet overdraagbaar gedrag" voor overdraagbaarheid onderwerpen).

Behalve als wzr NULL is, zou het moeten zijn teruggegeven door een eerdere aanroep van malloc() of gerelateerde functies. Als het gebied waar naar gewezen wordt verplaatst werd dan werd een free(wzr) uitgevoerd.

  reallocarray()
De reallocarray() functie verandert de grootte van het blok (verplaatst dit mogelijk) aangewezen door ptr om groot genoeg te zijn voor een tabel van nmemb elementen, elk met een grootte van grootte bytes. Dit is equivalent aan de aanroep:

    realloc(ptr, nmemb * grootte);

Echter, anders dan de realloc() aanroep, reallocarray() faalt veilig in het geval dat de multiplicatie zou overlopen. Als zo een overloop optreed, reallocarray() retourneert een NULL.

EIND WAARDE
De malloc, calloc(), realloc() en reallocarry() functies retourneren een wijzer naar het gereserveerde geheugen, dat geschikt is opgelijnd voor elk ingebouwd type dat past in de beschikbare ruimte. Bij een fout, retourneren deze functies NULL en zetten errno. Proberen te reserveren van meer dan PTRDIFF_MAX bytes wordt gezien als een fout, omdat een object van deze grootte later kan leiden tot overlopen bij het aftrekken van wijzers.

De free() functie geeft geen waarde terug, en behoudt errno.

De realloc() en reallocarray() functies retourneren een wijzer naar het nieuw gereserveerde geheugen, dat geschikt is opgelijnd voor elk ingebouwd type of NULL als de wzr niet NULL is en de gevraagde grootte nul is. (Zie "Niet overdraagbaar gedrag" voor overdraagbaarheids onderwerpen). dDe teruggegeven wijzer kan dezelfde zijn als wzr als de reservering niet was verplaatst (b.v. er was ruimte om de ruimte uit te breiden), of verschillend van wzr als de reservering was verplaatst naar een nieuw adres. Als deze functies falen, dan wordt het originele blok niet aangetast; het wordt niet verplaatst of vrij gegeven.

FOUTEN
calloc(), malloc(), realloc(), en reallocarray() kunnen falen met de volgende fout:

ENOMEM
    Geen geheugen meer. Mogelijk, het programma bereikte de RLIMIT_AS of RLIMIT_DATA limiet beschreven in getrlimit(2). Een andere reden zou kunnen zijn dat het aantal mappings die aangemaakt worden door het aanroepende proces de limiet zoals aangegeven door /proc/sys/vm/max_map_count hebben overschreden.

ATTRIBUTEN
Voor een uitleg van de termen in deze sectie, zie attributes(7).
Interface | Attribuut | Waarde
malloc(), free(), calloc(), realloc() | Thread veiligheid | MT-Safe

VOLDOET AAN

malloc()
free()
calloc()
realloc()
    C11, POSIX.1-2008.

reallocarray()
    Geen.

GESCHIEDENIS

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

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

malloc() en gerelateerde functies verwerpen groottes groter dan PTRDIFF_MAX vanaf glibc 2.30.

free() behoudt errno vanaf glibc 2.33.

OPMERKINGEN
Standaard volgt, Linux een optimistische geheugen toewijzing strategie. Dit betekent dat wanneer malloc() een niet-NULL terug geeft returns dat er nog geen garantie is dat het geheugen ook daadwerkelijk beschikbaar is. In het geval dat blijkt dat het systeem geen vrij geheugen meer heeft, dan worden een of meer processen vernietigd door de OOM vernietiger. Voor meer informatie, zie de beschrijving van /proc/sys/vm/overcommit_memory en /proc/sys/vm/oom_adj in proc(5), en het Linux kernel bron code bestand and the Linux Documentation/vm/overcommit-accounting.rst.

Normaliter kent malloc() geheugen toe van de heap en past de grootte van de heap aan zoals vereist, gebruikmakende van sbrk(2). Bij het toekennen van blokken geheugen groter dan MMAP_THRESHOLD bytes kent de glibc malloc() implementatie het geheugen toe als een private anoniem tabel met behulp van mmap(2). MMAP_THRESHOLD is standaard 128 kB, maar is instelbaar m.b.v. mallopt(3). Voor Linux 4.7 werden toekenningen gedaan met mmap(2) niet beïnvloed door de RLIMIT_DATA bron limiet; vanaf Linux 4.7, wordt deze limiet afgedwongen voor toekenningen gedaan met mmap(2).

Om corruptie in multi-threaded applicaties te vermijden worden semaforen intern gebruikt om geheugen-management data structuren die deze functies gebruiken te beschermen. In een multi-threaded application waarin threads gelijktijdig geheugen toekennen en vrijgeven kan er een botsing zijn voor deze semaforen. Om schaalbaar geheugen toekenning te kunnen afhandelen in een multi-threaded applicatie creëert glibc additionele memory allocation areas zodra semafoor botsingen worden gedetecteerd. Elk gebied is een grote geheugen regio die intern toegekend wordt door het systeem (m.b.v. brk(2) of mmap(2)), en bewaakt met zijn eigen semaforen.

Als uw programma een privé geheugen reservering gebruikt, dan dient het dit te doen door vervangen van malloc(), free(), calloc(), en realloc(). De vervangings functies moeten het gedocumenteerde glibc gedrag, inclusief errno afhandeling, grootte-nul toekenning, en controle van overloop implementeren, anders kunnen bibliotheek functies crashen of niet correct werken. Bij voorbeeld, als de vervanging van free() errno niet behoudt dan kunnen ogenschijnlijk niet gerelateerde bibliotheek functie falen zonder een geldige reden in errno. Privé geheugen reserveringen kunnen ook andere glibc functies vervangen; zie "Vervangen van malloc" in de glibc handleiding voor details.

Crashes in bij het toewijzen van geheugen zijn bijna altijd gerelateerd aan corruptie van de heap, zoals overlopen van een toegekend gebied or twee keer vrij geven van dezelfde wijzer.

De malloc() implementatie is aanpasbaar via omgeving variabelen; zie mallopt(3) voor details.

  Niet overdraagbaar gedrag
Het gedrag van deze functies wanneer de gevraagde grootte nul is, is glibc afhankelijk; andere implementaties kunnen NULL teruggeven zonder errno te zetten. Overdraagbare POSIX programma´s moeten dit gedrag tolereren. Zie realloc(3p).

POSIX vereist dat geheugen toewijzingen op errno worden gezet bij een fout. Hoewel de C standaard dat niet vereist, en applicaties die overgezet worden naar niet-POSIX platformen moeten hier niet van uit gaan.

Overdraagbare programma´s moeten geen privé geheugen reserveringen gebruiken, omdat POSIX en de C standaard geen vervanging van malloc(), free(), calloc(), en realloc() toestaan.

VOORBEELDEN
    #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 nmemb, 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 nmemb, size_t size)
    {
        return reallocarray(NULL, nmemb, size);
    }

ZIE OOK
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)

Voor details over de GNU C library implementatie, zie https://sourceware.org/glibc/wiki/MallocInternals.

VERTALING
De Nederlandse vertaling van deze handleiding is geschreven door Jos Boersema <joshb@xs4all.nl>, Mario Blättermann <mario.blaettermann@gmail.com> en Luc Castermans <luc.castermans@gmail.com>

Deze vertaling is vrije documentatie; lees de GNU General Public License Version 3 (https://www.gnu.org/licenses/gpl-3.0.html) of later over de Copyright-voorwaarden. Er is geen AANSPRAKELIJKHEID.

Indien U fouten in de vertaling van deze handleiding zou vinden, stuur een e-mail naar debian-l10n-dutch@lists.debian.org.