Pointer (programmeerconcept)

geheugenadres als variabele

Een pointer is in een programmeertaal een variabele die als waarde een geheugenadres bevat.

Pointer a wijst naar de gewone variabele b. a bevat het geheugenadres van b (1008 hexadecimaal), b bevat het getal 17 (11 in hexadecimaal).

De waarde van een pointer kan het adres van een variabele zijn (mogelijk een andere pointer), maar het kan ook naar een willekeurig ander adres verwijzen, bijvoorbeeld een stuk gealloceerd geheugen, of zelfs een functie.

Beschikbaarheid in programmeertalen bewerken

Veel traditionele programmeertalen als bijvoorbeeld C hebben uitgebreide mogelijkheden om met pointers te werken. Dit levert grote flexibiliteit op (bijvoorbeeld in vergelijking met een taal als Fortran 77 dat slechts zeer beperkte pointers kent), maar ook maakt het werken met pointers en berekeningen aan pointers in dergelijke programmeertalen het vaak erg moeilijk om foutloze programma's te schrijven die er correct voor zorgen dat ze de geheugenplaatsen op de juiste manier reserveren en vrijgeven. Omdat een pointer naar een geheugenadres wijst kan hij ook, door onvoorzichtig of foutief programmeren, naar een verkeerd geheugenadres gaan wijzen waar het programma niets te zoeken heeft en zo andere gegevens van het programma wijzigen of (indien daartegen geen bescherming is) gegevens van andere programma's of zelfs het draaiende operating system beschadigen waardoor het hele systeem herstart moet worden. Dergelijke bugs zijn vaak lastig op te sporen.

In modernere objectgeoriënteerde scripttalen worden geen pointers meer op deze manier gebruikt. Intern worden nog wel pointers gebruikt, maar doordat ze voor de programmeur worden afgeschermd en de programmeertalen zelf voor het reserveren en vrijgeven van de nodige geheugenplaatsen zorgen, wordt het programmeren van ingewikkelde constructies fundamenteel eenvoudiger. Er zijn twee technieken die in zulke programmeertalen gebruikt worden om niet gebruikte ruimte automatisch weer vrij te geven:

  • door bij te houden hoeveel verwijzingen er naar een variabele zijn, en de ruimte automatisch vrij te geven zodra het aantal verwijzingen nul wordt (reference counting)
  • door regelmatig door het hele geheugen te spitten, en de ruimte vrij te geven van variabelen die niet meer gebruikt worden (garbage collecting)

Beide methoden hebben hun voor- en nadelen, ze worden dan ook soms gecombineerd.

Handles bewerken

Het veelvuldig gebruik van dynamische geheugenallocatie kan resulteren in fragmentatie van het gebruikte geheugen. Het is heel moeilijk om dat probleem op te lossen. Een systeem dat door Apple ooit op de originele Apple Macintosh met 68000-processor werd geïntroduceerd om fragmentatie van het geheugen op te lossen is het gebruik van handles: pointers naar pointers. Als een programma alleen handles gebruikt, kan een bibliotheek worden gebruikt die automatisch het gebruikte geheugen naar behoeven defragmenteert.

Referenties bewerken

In talen als Perl of Java kan veel van de functionaliteit van pointers worden gebruikt door gebruik te maken van referenties (references). Men kan op een eenvoudige manier complexe datastructuren maken, door bijvoorbeeld een array te gebruiken die referenties bevat naar associatieve arrays die op hun beurt referenties bevatten naar weer andere datastructuren. Hierbij hoeft de programmeur niet expliciet geheugenadressen te gebruiken.

De kenmerkende verschillen tussen referenties en pointers zijn:

  • Een referentie kan alleen naar een bestaand object verwijzen, een pointer naar een willekeurig geheugenadres.
  • Met een pointer kunnen berekeningen worden uitgevoerd om andere adressen te bepalen (de waarde van de pointer + 2 maal de lengte van het datatype int + 1), met een referentie kan dat niet.

Anders gezegd: een pointer biedt een inkijk in het onderliggende geheugenmodel, een reference speelt zich strikt af binnen het domein van de programmeertaal. Een pointer is een primitiever concept, waarmee meer mogelijk is, maar waarmee ook meer mis kan gaan.