Zeiger und Arrays in C sind verwandt, aber sie sind nicht dasselbe:
Beim Übergeben eines Arrays an eine Funktion wird faktisch ein Zeiger auf das erste Element des Arrays übergeben (deshalb gibt sizeof innerhalb der Funktion nicht die Größe des gesamten Arrays, sondern nur die Größe des Zeigers zurück).
Syntax der Übergabe:
void foo(int arr[], int size) { // arr — faktisch int* for (int i = 0; i < size; ++i) printf("%d ", arr[i]); } int main() { int data[5] = {1,2,3,4,5}; foo(data, 5); }
Frage: Was gibt der Ausdruck sizeof(arr) innerhalb der Funktion zurück, wenn arr ein Parameter vom Typ int arr[] ist?
Antwort: Gibt die Größe des Zeigers zurück (sizeof(int*)), aber nicht die Größe des gesamten Arrays. Denn es wird ein Zeiger auf das erste Element an die Funktion übergeben, damit geht die Information über die Länge verloren.
void printSize(int arr[]) { printf("%zu ", sizeof(arr)); // sizeof(int*) normalerweise 4 oder 8 }
Geschichte
In einem kommerziellen Projekt wurde ein Code geschrieben, um den Durchschnittswert in einem Array zu berechnen, bei dem die Anzahl der Elemente innerhalb der Funktion sizeof(arr) / sizeof(arr[0]) verwendet wurde, was immer 1 oder 2 anstelle der tatsächlichen Anzahl der Elemente zurückgab. Dadurch arbeitete das Programm fehlerhaft mit den Daten und berechnete die Werte nicht korrekt.
Geschichte
In einem Projekt wurde ein dynamisch allokiertes Array an eine Funktion übergeben, ohne die Länge (size) separat zu speichern. Infolgedessen wusste die Funktion nicht, wie viele Elemente zugewiesen waren, was zu Überschreitungen, Speicherlecks oder Speicherbeschädigungen führte.
Geschichte
Aus Versehen wurde ein Array fester Größe als Zeiger verwendet, und in einigen Compilern war eine direkte Zuweisung über memcpy des gesamten Arrays anstelle seiner Elemente erlaubt. Dies führte zu der schwer nachvollziehbaren Fehlfunktion, dass Teile der Datenstruktur verloren gingen oder ein Stack Overflow auftrat.