Kunnen meerdere pointers naar dezelfde variabele in C verwijzen?

8

Het is een eigenaardigheid van C waar beginners vaak over struikelen, maar het voelt als magie zodra het klikt: je kunt een tiental verwijzingen hebben die allemaal naar hetzelfde geheugenadres staren.

Overweeg dit scenario. Je declareert een geheel getal i. Vervolgens declareer je drie pointers p, q en r. Je wijst ze allemaal toe aan het adres i.

Kijk eens naar die laatste regel. r hoeft niet direct over i te weten. Het verwijst gewoon naar waar ‘p’ naar verwijst. En p wijst naar i. Dus r verwijst ook naar i.

De toewijzingsoperator kopieert hier het adres, niet de waarde. Als je r = p doet, kopieer je niet het gehele getal binnen i. U kopieert de geheugenlocatie die p bevat.

Nadat deze code is uitgevoerd, heeft i feitelijk vier namen. Je kunt er toegang toe krijgen via i. Je kunt er toegang toe krijgen via *p. Je kunt er toegang toe krijgen via *q. Of u kunt er toegang toe krijgen via *r.

Er is geen technische limiet voor het aantal pointers dat u op deze manier kunt stapelen.

Waarom dit belangrijk is

Dit is niet alleen academische syntaxis. Het verandert de manier waarop u over gegevensstromen denkt.

In talen met strikte objectreferenties creëert het kopiëren van een object vaak een nieuw exemplaar in het geheugen. In C is het kopiëren van een pointer goedkoop. Het is gewoon een geheugenadres. Snel. Klein.

Hierdoor kunnen meerdere delen van uw code dezelfde gegevens manipuleren zonder duplicatie. Wijziging *p en *q ziet de wijziging onmiddellijk.

U maakt aliassen voor het geheugen.

Het risico van alias

Hier wordt het ‘coole aspect’ een probleem.

Als p, q en r allemaal naar i verwijzen, kan elk van hen i wijzigen.

Nu is i 10. *q is 10. *r is 10.

Maar wat als je vergeet dat r ook naar i kijkt? Je zou kunnen aannemen dat i stabiel is omdat je het niet rechtstreeks hebt aangeraakt. Je hebt alleen ‘*q’ aangeraakt.

Het is een gedeelde bron. En gedeelde bronnen zijn de plek waar raceomstandigheden en onverwachte overschrijvingen leven.

Hoe u onbedoelde bijwerkingen kunt voorkomen

Als je er zeker van wilt zijn dat de ene pointer niet per ongeluk gegevens overschrijft die voor een andere pointer bedoeld zijn, gebruik je const.

Nu kan r i lezen. Het kan ernaar verwijzen. Het kan het niet veranderen.

Zo dwing je grenzen af in een taal die erop vertrouwt dat je het geheugen handmatig beheert.

Waar dit past in systeemprogrammering

Je ziet dit patroon overal in systeemcode.

Kernelstructuren hebben vaak meerdere verwijzingen naar hetzelfde besturingsblok. Apparaatstuurprogramma’s wijzen hetzelfde hardwareregister toe aan verschillende logische namen.

Als u begrijpt dat verwijzingen slechts labels voor adressen zijn, kunt u deze problemen oplossen. Als het geheugen beschadigd raakt, traceer dan de pointers. Wie nog meer