In de C-taal beheert de programmeur het geheugen direct: de plaatsing, vrijgave en het gebruik van arrays, structuren en pointers worden handmatig gecontroleerd. Mechanismen voor dynamische geheugentoewijzing bestaan al sinds de jaren '70 in C en worden geïmplementeerd via speciale functies van de standaardbibliotheek (malloc, calloc, realloc, free). Deze aanpak biedt prestaties en flexibiliteit, maar vereist nauwkeurigheid.
Fouten bij het werken met geheugen kunnen leiden tot lekken, beschadiging van andere gegevens, crashes van het programma of beveiligingskwetsbaarheden. Vaak gebeurt de fout door vergeten aanroepen van free, het overschrijden van de grenzen van een array, onjuiste typecasting van pointers of dubbele vrijgave van geheugen. Voor structuren is de situatie vergelijkbaar, maar er is een extra risico dat vergeten wordt om geneste dynamische velden schoon te maken.
Om fouten te minimaliseren, wordt aangeraden om strikt gestructureerde code te ontwikkelen, alle toewijzingen en vrijgaven van geheugen bij te houden, niet-vrijgegeven pointers te vermijden en de grootte van toegewezen arrays bij te houden. Het is belangrijk om statische analysehulpmiddelen, eindcontroles (valgrind, sanitizers) te gebruiken, en ook om overeenkomsten na te leven: wie malloc heeft aangeroepen, die bevrijdt ook het geheugen.
Voorbeeldcode:
#include <stdio.h> #include <stdlib.h> typedef struct { int *arr; size_t size; } ArrayWrapper; ArrayWrapper *create(size_t n) { ArrayWrapper *aw = malloc(sizeof(ArrayWrapper)); if (!aw) return NULL; aw->arr = malloc(sizeof(int) * n); if (!aw->arr) { free(aw); return NULL; } aw->size = n; return aw; } void destroy(ArrayWrapper *aw) { if (aw) { free(aw->arr); free(aw); } }
Belangrijkste kenmerken:
Wat gebeurt er als geheugen wordt vrijgegeven via een null-pointer (free(NULL))?
Volgens de C-standaard is het aanroepen van free op een null-pointer veilig — er gebeurt niets, er treedt geen fout op. Dit is handig voor het overdragen van de verantwoordelijkheid voor het vrijgeven van geheugen.
Mag geheugen worden gebruikt na het aanroepen van free?
Nee, het gebruik van geheugen na vrijgave (use-after-free) is een klassieke fout. Gegevens kunnen veranderen of de regio kan aan een ander proces worden toegewezen. Het is altijd aan te raden om de pointer na free op null te zetten.
int *ptr = malloc(10); free(ptr); ptr = NULL; // Betrouwbaar
Is het verplicht om al het toegewezen geheugen vrij te geven voordat het programma wordt afgesloten?
Technisch gezien is het niet verplicht — bij het afsluiten van het programma bevrijdt het OS alle middelen. Maar het negeren van het vrijgeven van geheugen is een antipatroon, dat debugging bemoeilijkt en leidt tot fouten in grote, langdurige programma's.
Een ontwikkelaar creëert dynamische arrays binnen een functie, en vergeet deze op te schonen:
Voordelen:
Nadelen:
De gehele code doorloopt een statische analyse, alle pointers worden na free op null gezet, elke malloc gaat gepaard met een free:
Voordelen:
Nadelen: