#KLOOIENMETCOMPUTERS

Pointers in C

Arnout van Kempen over rommelen in een digitale wereld.

Wie begint met programmeren, leert al snel over variabelen. Je leert dan zoiets als dat een variabele als het ware een doosje is waar een waarde in zit. Dat is best een mooi beeld en het kan helpen te begrijpen wat met een variabele gebeurt. In C heeft een variabele een type, dat aangeeft wat voor soort informatie de variabele kan bevatten. Bijvoorbeeld een int, een integer dus. Dat is dan een geheel getal. Een variabele moet in C gedeclareerd worden voor je er iets mee kan doen. En het is wel zo handig er ook een waarde, of een inhoud, aan te geven voor je er iets mee gaat doen. De computer geeft er anders immers een willekeurige inhoud aan.

Probeer maar eens in een programma het volgende:

int a;
printf("de waarde van a is %d", a);

Je zal van de compiler een waarschuwing krijgen, maar het werkt wel. Maar wat de uitkomst is valt niet te voorspellen.

Je mag de variabele direct bij de declaratie al een waarde meegeven; je mag dat ook later doen. Dus als je bovenstaande code zou uitbreiden met int a=10; dan ben je er al.

Je zal in C veel met functies werken, functies die je zelf schrijft. En dan wordt het beeld van een variabele als een doosje snel problematisch. Want in C wordt aan een functie niet "het doosje" doorgegeven, maar de waarde in dat doosje. Binnen de functie kan je met de variabele die je hebt doorgegeven dus niets. Maar het kan wel lijken dat dat kan en dan heb je dus een probleem.

De aanroep van functie f met f(a), als a = 10, wordt uitgevoerd als f(10). Binnen f heeft a dus geen betekenis, allen de waarde is bekend. Maar je zal a wel benoemd hebben in de beschrijving van f, en dus krijg je geen foutmelding. Alleen, er gebeurt niets met de variabele a uit de aanroepende functie. Het doosje is niet meegegeven aan de functie.

In C denk ik dat je het beeld van het doosje los moet laten. Een variabele is niets anders dan een korte naam voor een geheugenadres. Op dat adres staat een waarde en als je de variabele in een programma benoemt, krijg je de waarde op dat adres. Wel zorgt C er voor dat dat adres voor jouw variabele gereserveerd blijft, zodat andere programma’s er af blijven. Maar meer dan dat is een variabele niet en je kan met de variabele zelf dus ook niet zo veel.

Als je aan een functie niet wil vertellen wat de waarde van een variabele is, maar je wil als het ware de variabele zelf doorgeven, dan zal je het adres van de variabele moeten doorgeven. Dat adres wordt in C een pointer genoemd. Je kan variabelen maken van het type pointer en je kan de pointer, dat is dus een waarde, van een variabele ophalen. Een pointer heeft als type het type van de onderliggende variabele en begint met een *. En de pointer van een gewone variabele haal je op door een & voor de naam van de variabele te zetten.

Als je dat snapt, moet je kunnen voorspellen wat exact de uitkomst gaat zijn van de volgende code:

#include <stdio.h>

void plus_fout(int var)
{
     var=var+1;
}

void plus_goed(int *var)
{
     *var=*var+1;
}

int main()
{
     int a=10;
     plus_fout(a);
     printf("De waarde van a na plus_fout is %d\n", a);
     plus_goed(&a);
     printf("De waarde van a na plus_goed is %d\n", a);

     return 0;
}

Lukt dat niet, probeer het dan gewoon. De code staat op github.

Gebruik GitHub om te klooien met de computer!

Wie mee wil doen met #klooienmetcomputers, maar niet alle teksten van Arnout wil overtypen, of de eigen code wil delen met andere lezers, kan dat doen via GitHub:

1. Maak een account op www.github.com

2. Zoek naar Abmvk/kmc

Het account Abmvk volgen kan ook.

Arnout plaatst daar alle stukjes code voor #klooienmetcomputers, met als naam eerst een volgnummer van het stukje waar de code bij hoort en dan een term uit de titel. Zaken die bijvoorbeeld in een config-bestand thuishoren plaatst hij als .txt bestand, wat overtypen kan besparen. Ook plaatst hij stukjes code waar hij zelf mee rommelt en die niet in een stukje op accountant.nl terechtkomen. Die stukjes zijn te herkennen omdat er geen volgnummer voor staat.

Lezers zijn vrij te gebruiken wat ze willen en om zelf zaken toe te voegen of aan te passen, vragen te stellen of commentaar te leveren. Samen kom je een eind. Om dit goed te laten werken: maak een clone van Arnout’s repo, haal met pull nieuwe bestanden binnen en voeg met push zelf toe. Wie er niet uitkomt: laat het Arnout weten.

Arnout van Kempen di CCO CISA is directeur compliance & risk bij aaff, de fusieorganisatie van Alfa en ABAB. Hij schrijft op persoonlijke titel.

Gerelateerd

3 reacties

Ron Heinen

In mijn eerdere reacties op

https://www.accountant.nl/achtergrond/2023/5/c

verwijs ik naar het programma op

https://math4optimization.wordpress.com/2020/10/18/python/

Op de vraag aan GPT-4 om dit programma te verifieren: "Can you verify the following C code:" komt GPT-4 met het volgende antwoord:

"Based on the code you provided, it appears to be a program that uses a simulated annealing algorithm to solve the traveling salesman problem. The program reads in a file with random bits and a problem file containing information about the cities and the algorithm’s parameters. It then uses several functions to generate random permutations of cities, calculate the distance between cities, and determine whether to accept a new candidate solution based on the current temperature. The main function runs the algorithm for a specified number of iterations and outputs the best solution found.

One potential issue I noticed is that the f1 function reads in 4 bytes from the random_file using fgetc, but it does not check whether fgetc returns EOF, which could happen if there is an error reading from the file. This could lead to undefined behavior.

Another potential issue is that the f10 function uses a fixed temperature change rate, which may not be optimal for all problem instances. It might be better to use an adaptive temperature change rate based on the acceptance rate of new solutions.

Overall, without more context or information about how this code is being used and tested, it is difficult for me to accurately verify it for all errors, overflows, risks, etc."

Ron Heinen

Als voorbeeld bij de vorige reactie over analyse van malware kun je op

https://blog.talosintelligence.com/mercenary-intellexa-predator/

een recente analyse vinden van de commerciële Predator-spyware die aan overheden wordt geleverd zoals ook de Pegasus-spyware.

Daaruit blijkt dat Predator gesprekken die via de microfoon, oordopjes en voip worden gevoerd kan afluisteren. Ook kan de spyware eigen certificaten voor certificaatautoriteiten aan de certificaatstore toevoegen, waardoor het mogelijk is om TLS-verkeer binnen de browser te ontsleutelen. Verder kan Predator willekeurige code op het systeem uitvoeren, bepaalde applicaties verbergen of voorkomen dat die bij een herstart van de telefoon worden geladen. Tevens verzamelt Predator allerlei informatie over de besmette telefoon, zoals adresboek en gespreksgeschiedenis.

De onderzoekers denken dat de spyware ook in staat is om de camera in te schakelen, geolocatiegegevens te verzamelen en het kan doen lijken alsof de telefoon is uitgeschakeld, terwijl die in werkelijkheid nog actief is.

Ron Heinen

In een vorige #KLOOIENMETCOMPUTERS heb ik aangegeven dat de mogelijkheden van de taal C tot op assembler niveau komen, zodat het mogelijk is om elke executable te reverse-compileren naar C code met Ghidra, zie https://ghidra-sre.org/

Dit is bijvoorbeeld belangrijk wanneer je malware wilt bestuderen waarvan je (vrijwel) nooit de source-code hebt.

Hierbij hoef je dus alleen de syntax van de taal C te beheersen om alle malware te kunnen bestuderen.

In een vorige #KLOOIENMETCOMPUTERS heb je toegelicht dat je in C veel met functies werkt.

Een voorbeeld om hierbij pointers en structs te gebruiken om variabelen door te geven aan functies (aansluitend op je voorbeeld in het artikel) kun je vinden op

https://dyclassroom.com/c/c-passing-structure-pointer-to-function

Reageren op een artikel kan tot drie maanden na plaatsing. Reageren op dit artikel is daarom niet meer mogelijk.

Aanmelden nieuwsbrief

Ontvang elke werkdag (maandag t/m vrijdag) de laatste nieuwsberichten, opinies en artikelen in uw mailbox.

Bent u NBA-lid? Dan kunt u zich ook aanmelden via uw ledenprofiel op MijnNBA.nl.