Achtergrond:
Pointerarithmetic is geïntroduceerd in de programmeertaal C om een efficiënte werkwijze met geheugen, arrays en structuren te waarborgen. Het is nauw verbonden met geheugenadressering en hoe C op het laagste niveau werkt — optelling of aftrekking van een pointer maakt het mogelijk om toegang te krijgen tot opeenvolgende elementen van een array.
Probleem:
De grootste moeilijkheid ligt in het feit dat pointerarithmetic niet gelijkwaardig is aan de arithmetic van getallen: het optellen van 1 bij een pointer verhoogt deze met de grootte van het type waarnaar hij wijst. Klassieke fouten zijn onder andere het overschrijden van de grenzen van een toegewezen array, werken met pointers van incompatibele types en pogingen tot berekeningen met void *.
Oplossing:
Altijd de grootte van het type in overweging nemen bij het werken met pointers, vermijden van algebraïsche berekeningen met void*, en de arraygrenzen controleren. Gebruik indexering of berekende pointers om toegang te krijgen tot een element van de array, en controleer vooraf de grenzen.
Voorbeeldcode:
#include <stdio.h> int main() { int arr[5] = {1, 2, 3, 4, 5}; int *p = arr; printf("%d\n", *(p + 2)); // 3 // Ongeldig: p + 10 overschrijdt de grenzen van de array return 0; }
Belangrijke kenmerken:
Mag je een waarde van het type float of variabelen van andere types bij een pointer optellen?
Nee, je kunt alleen waarden van een geheel type bij pointers optellen of aftrekken. Het gebruik van drijvende-komma zal leiden tot een compilatiefout.
*Zullen (arr + i) en arr[i] altijd hetzelfde retourneren, zelfs als i uit de grenzen van de array valt?
Nee. Semantisch zijn ze gelijkwaardig, maar als de index buiten de grenzen van de array valt, leiden beide expressies tot ongedefinieerd gedrag (undefined behavior).
Wat zal er gebeuren bij het aftrekken van pointers die naar verschillende arrays verwijzen?
Het resultaat is niet gedefinieerd door de standaard en wordt als een fout beschouwd. Je mag alleen pointers van binnen dezelfde array (of geheugen dat met één blok is toegewezen) van elkaar aftrekken.
buffer overrun)In de code gebruikt de ontwikkelaar pointerarithmetic om door een array te itereren:
Voordelen:
Nadelen:
In de herfactoriseerde versie worden expliciete grenscontroles gebruikt bij elke stap:
Voordelen:
Nadelen: