ProgrammatieC ontwikkelaar

Wat gebeurt er wanneer een structuur als waarde naar een functie wordt doorgestuurd en hoe beïnvloedt dit de prestaties en semantiek van het programma?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord

In de programmeertaal C, wanneer een structuur als waarde naar een functie wordt doorgestuurd, wordt er een volledige kopie van de structuur gemaakt in het tijdelijke geheugengebied (meestal op de stack van de functie). Dit betekent dat eventuele wijzigingen binnen de functie de originele instantie van de structuur buiten de functie niet beïnvloeden.

Wanneer je grote structuren als waarde doorgeeft, krijg je te maken met tijd- en geheugenlasten door de noodzaak om alle leden van de structuur te kopiëren. Daarom is het een standaardpraktijk om een pointer naar de structuur door te geven:

#include <stdio.h> struct Data { int arr[1000]; int flag; }; void modify_by_value(struct Data d) { d.flag = 10; // Wijzigt alleen de lokale kopie } void modify_by_pointer(struct Data *d) { d->flag = 20; // Wijzigt het origineel } int main() { struct Data data = { {0}, 0 }; modify_by_value(data); // data.flag == 0 modify_by_pointer(&data); // data.flag == 20 return 0; }

Voordelen van doorgeven via pointer:

  • Geen kosten voor het kopiëren van grote hoeveelheden gegevens
  • De originele structuur kan worden gewijzigd

Nadelen van doorgeven als waarde:

  • Tijd- en ruimtebestedingen voor kopiëren
  • Verhoogd stackverbruik (vooral op microcontrollers)

Misleidende vraag

Wat gebeurt er als een functie een structuur als waarde retourneert? Wat zijn de risico's?

Antwoord:

In C is het mogelijk om een structuur als waarde uit een functie te retourneren, bijvoorbeeld:

struct Point { int x, y; }; struct Point make_point(int x, int y) { struct Point p = {x, y}; return p; // een kopie wordt geretourneerd }

Het belangrijkste risico is de prestaties: er wordt een kopie van de structuur gemaakt en geretourneerd. Bovendien, bij het onjuist retourneren van het adres van een lokale variabele, kan de structuur naar ongeldig geheugen verwijzen:

struct Point* bad() { struct Point p = {1, 2}; return &p; // fout: retourneren van het adres van een lokale variabele }

Voorbeelden van echte fouten door onbekendheid met de nuances van het onderwerp


Verhaal

Op embedded apparaten met een kleine stack, heeft een ontwikkelaar een grote structuur (1 KB) als waarde doorgegeven, wat leidde tot stack overflow en sporadische systeembelasting. Onderzoek toonde aan dat het kopiëren van elke structuur leidde tot een tekort aan stackgeheugen bij diepe oproepnesten.


Verhaal

In een bedrijfsserversysteem heeft een programmeur een pointer naar een lokale structuur geretourneerd, en in de code ontstond toegang tot "hangende" pointers na het verlaten van de functie. Dit resulteerde in een kritieke segfault in productie met zeldzame reproduceerbaarheid.


Verhaal

In een Open Source-project daalden de prestaties scherp na de overstap naar een functie die een complexe structuur met interne arrays als waarde retourneert. De profiler onthulde de CPU-tijdslasten als gevolg van onnodig herhaald kopiëren van structuren.