I puntatori e gli array in C sono correlati, ma non sono la stessa cosa:
Quando si passa un array a una funzione, in effetti si passa un puntatore al primo elemento dell'array (quindi sizeof all'interno della funzione non restituisce la dimensione dell'intero array, ma solo la dimensione del puntatore).
Sintassi di passaggio:
void foo(int arr[], int size) { // arr — in effetti int* for (int i = 0; i < size; ++i) printf("%d\n", arr[i]); } int main() { int data[5] = {1,2,3,4,5}; foo(data, 5); }
Domanda: Cosa restituisce l'espressione sizeof(arr) all'interno della funzione, se arr è un parametro di tipo int arr[]?
Risposta: Restituisce la dimensione del puntatore (sizeof(int*)), e non la dimensione dell'intero array. Perché viene passato un puntatore al primo elemento, l'informazione sulla lunghezza va persa.
void printSize(int arr[]) { printf("%zu\n", sizeof(arr)); // sizeof(int*) di solito 4 o 8 }
Storia
In un progetto commerciale è stato scritto un codice per calcolare la media dei valori in un array, dove per il numero di elementi all'interno della funzione si utilizzava sizeof(arr) / sizeof(arr[0]), che restituiva sempre 1 o 2 invece del reale numero di elementi. A causa di ciò, il programma lavorava in modo errato con i dati e calcolava in modo errato i valori medi.
Storia
In un progetto, un array allocato dinamicamente è stato passato a una funzione senza una memoria separata per la lunghezza (size). Di conseguenza, la funzione non sapeva quanti elementi erano allocati, portando a errori di superamento dei limiti, perdite di memoria o corruzione della memoria.
Storia
Per errore, è stato utilizzato un array di dimensioni fisse come puntatore, e in alcuni compilatori era consentita l'assegnazione diretta tramite memcpy dell'intero array invece dei suoi elementi. Questo ha portato a errori poco evidenti, con parti della struttura dei dati perse o un overflow dello stack.