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:
sizeof(arr) - dit retourneert de grootte van de pointer, niet de array.Veilig en correct werken met arrays kan op de volgende manieren:
const int *arr door.Vraag: Is het mogelijk om de grootte van de doorgegeven oorspronkelijke array binnen de functie te achterhalen via het argument
int arr[]metsizeof(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) }
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.