Achtergrond van de vraag: De programmeertaal C is altijd flexibel geweest wat betreft typeconversie, om het werken met low-level geheugen en verschillende platforms te vereenvoudigen. Echter, de beknoptheid en kracht ervan kunnen gemakkelijk leiden tot kwetsbaarheden en defecten die verband houden met onjuiste typecasting, vooral bij het werken met pointers en bitwise aritmetiek.
Probleem:
Oplossing:
Voorbeeldcode:
#include <stdio.h> void print_double_as_int(double d) { int i = (int)d; printf("Waarde: %d\n", i); } void *ptr = malloc(16); int *ip = (int*)ptr; // Toegang tot raw geheugen: toegestaan als ptr daadwerkelijk naar een int verwijst
Belangrijke kenmerken:
1. Wanneer is het toegestaan om een void naar een pointer naar een structuur te casten, en is dit altijd veilig?*
Dergelijke casting is veilig als het adres daadwerkelijk naar een instantie van die structuur verwijst, anders is het gedrag ongedefinieerd (undefined behavior).
2. Wat gebeurt er als je een pointer naar een structuur van gelijke lengte cast naar een pointer naar een structuur met minder of meer velden?
Toegang tot de velden van de "nieuwe" structuur zal leiden tot lezen/schrijven buiten de grenzen van de oorspronkelijke structuur, wat kan leiden tot gegevensbeschadiging.
Voorbeeldcode:
typedef struct {int a;} S1; typedef struct {int a; int b;} S2; S1 s; S2 *ps2 = (S2*)&s; // ps2->b — toegang tot "rommel"
3. Is het veilig om een pointer naar int te casten naar een pointer naar char voor toegang tot de bytes van dat getal?
Dit is een typische techniek voor geheugenbeheer — toegang op byte-niveau is toegestaan, maar vereist voorzichtigheid, aangezien er problemen kunnen zijn met uitlijning en de bytevolgorde afhankelijk is van de architectuur (big-endian/little-endian).
Een junior programmeur optimaliseerde de toegangstijd door een netwerkpakket te verwerken, en castte een pointer van een raw-array naar een pointer naar een datastructuur met velden van verschillende types.
Voordelen:
Nadelen:
Na aanpassing werd elke byte van het pakket handmatig geëxtraheerd via memcpy.
Voordelen:
Nadelen: