ProgrammatieC ontwikkelaar

Vertel in detail over het mechanisme van het doorgeven van arrays naar functies in de C-taal. Wat zijn de risico's die met dit model gepaard gaan, en hoe organiseer je veilig werken met arrays binnen functies?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord

In de C-taal worden arrays niet op waarde doorgegeven aan functies. Wanneer je een array als argument doorgeeft, ontvangt de functie daadwerkelijk een pointer naar het eerste element van de array. Dit leidt ertoe dat de functie de oorspronkelijke array wijzigt in plaats van een kopie ervan.

Bijvoorbeeld:

void fillArray(int arr[], int n) { for (int i = 0; i < n; ++i) arr[i] = i*i; } int main() { int myarr[5]; fillArray(myarr, 5); // ok }

Binnen de functie:

  • is het onmogelijk om de grootte van de oorspronkelijke array te achterhalen via sizeof(arr) - dit retourneert de grootte van de pointer, niet de array.
  • je kunt alleen werken met dat stuk geheugen waarvan de grootte je expliciet hebt doorgegeven.

Veilig en correct werken met arrays kan op de volgende manieren:

  • geef altijd de grootte van de array als een apart argument door;
  • gebruik constanten of macro-wrappers voor de groottes;
  • als je de array wilt beschermen tegen wijzigingen, geef dan const int *arr door.

Strikvraag

Vraag: Is het mogelijk om de grootte van de doorgegeven oorspronkelijke array binnen de functie te achterhalen via het argument int arr[] met sizeof(arr)?

Antwoord: Nee, dat is niet mogelijk! sizeof(arr) binnen de functie retourneert de grootte van de pointer naar het type (bijvoorbeeld 4 of 8 bytes), niet de grootte van de array.

Voorbeeld:

void f(int arr[]) { printf("%zu\n", sizeof(arr)); // grootte van de pointer, niet de array! } int main() { int x[10]; f(x); // Geeft meestal 8 weer (x86_64) of 4 (x86) }

Voorbeelden van echte fouten


Verhaal

In een industrieel project probeerde de functie voor het kopiëren van arrays de lengte van de array ter plekke te berekenen met sizeof(arr)/sizeof(int) binnen de functie. In de praktijk leidde dit ertoe dat alleen een deel van de array werd gekopieerd, omdat de grootte altijd gelijk was aan 1 (8/8), waardoor de gegevens op onvoorspelbare wijze werden overschreven.


Verhaal

In een netwerkapplicatie nam de functie voor het verzenden van gegevens een buffer aan in de vorm van een array zonder expliciete vermelding van de grootte, waardoor de hele buffer niet kon worden verzonden, of er vond een lezing van rommel buiten de grenzen van de array plaats, wat fouten bij het verzenden en instabiliteit van de verbinding veroorzaakte.


Verhaal

Bij het schrijven van een bibliotheek voor het werken met afbeeldingen had de programmeur de functie voor het inkleuren van een array van afbeeldingen niet voorzien van de verplichte grootteparameter. Dit leidde tot een bufferoverloop en een crash van het programma bij bepaalde ingangen, wat alleen werd ontdekt tijdens de integratietest van een grote afbeelding.