W języku C tablice nie są przekazywane do funkcji przez wartość. Jeśli przekażesz tablicę jako argument, do funkcji faktycznie trafia wskaźnik na pierwszy element tablicy. Prowadzi to do tego, że funkcja modyfikuje oryginalną tablicę, a nie jej kopię.
Na przykład:
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 }
Wewnątrz funkcji:
sizeof(arr) — zwróci to rozmiar wskaźnika, a nie tablicy.Aby poprawnie i bezpiecznie pracować z tablicami, możesz robić tak:
const int *arr.Pytanie: Czy można poznać rozmiar przekazanej tablicy wewnątrz funkcji przez argument
int arr[]za pomocąsizeof(arr)?
Odpowiedź: Nie, nie można! sizeof(arr) wewnątrz funkcji zwróci rozmiar wskaźnika na typ (na przykład, 4 lub 8 bajtów), a nie rozmiar tablicy.
Przykład:
void f(int arr[]) { printf("%zu\n", sizeof(arr)); // rozmiar wskaźnika, nie tablicy! } int main() { int x[10]; f(x); // Zwykle zwróci 8 (x86_64) lub 4 (x86) }
Historia
W projekcie przemysłowym funkcje kopiowania tablic próbowały obliczać długość tablicy w locie, używając
sizeof(arr)/sizeof(int)wewnątrz funkcji. W rezultacie prowadziło to do kopiowania tylko części tablicy, ponieważ rozmiar zawsze wynosił 1 (8/8), a dane były nadpisywane w nieprzewidywalny sposób.
Historia
W jednym z aplikacji sieciowych funkcja wysyłania danych przyjmowała bufor w postaci tablicy bez wyraźnego wskazania jego rozmiaru, przez co cały bufor nie zdążył się wysłać lub występowały odczyty śmieci poza granicami tablicy, co wywoływało błędy w przesyłaniu i niestabilność połączenia.
Historia
Przy pisaniu biblioteki do pracy z obrazami programista nie zaopatrzył funkcji kolorowania tablicy obrazów w obowiązkowy parametr rozmiaru. Doprowadziło to do przepełnienia bufora i awarii programu przy określonych danych wejściowych, co zostało wykryte dopiero w teście integracyjnym na dużym obrazie.