Verständnis von sizeof in C++: Warum ist n nicht gleich 8?

Wenn Sie mit Arrays in C++ arbeiten, können Sie unerwartete Ergebnisse in Bezug auf den sizeof-Operator antreffen, insbesondere beim Übergeben von Arrays an Funktionen. In diesem Blogbeitrag werden wir ein häufiges Missverständnis beleuchten, das beim Einsatz von sizeof mit Funktionsparametern auftritt, insbesondere die Frage beantworten: Warum ist n in der Funktion foo() nicht gleich 8?

Das Problem

Betrachten wir die zwei Codebeispiele, die das Problem veranschaulichen:

Beispiel 1: Funktion foo()

void foo(char cvalue[8])
{
    int n = sizeof(cvalue);
}

Im obigen Beispiel könnte man erwarten, dass n gleich 8 ist, da das Array mit einer Größe von 8 definiert ist. Dies ist jedoch nicht der Fall.

Beispiel 2: Funktion bar()

void bar()
{
    char cvalue[8];
    int n = sizeof(cvalue);
}

In diesem zweiten Beispiel ist sizeof(cvalue) gleich 8. Warum gibt es da einen Unterschied?

Das Konzept verstehen

Um zu verstehen, warum sizeof(cvalue) in jeder Funktion unterschiedliche Werte zurückgibt, müssen wir klären, wie Arrays in C und C++ behandelt werden.

Arrays als Funktionsparameter

Wenn Sie ein Array an eine Funktion in C oder C++ übergeben, übergeben Sie nicht tatsächlich das Array selbst. Stattdessen übergeben Sie einen Zeiger auf das erste Element des Arrays. Die in der Funktionsparameter-Deklaration verwendeten Klammern sind lediglich eine syntaktische Notation, die das Verhalten nicht ändert – alle folgenden Deklarationen sind äquivalent:

  • void foo(char cvalue[8])
  • void foo(char cvalue[])
  • void foo(char *cvalue)

In all diesen Deklarationen wird cvalue als Zeiger interpretiert. Daher gibt Ihnen der Aufruf von sizeof(cvalue) innerhalb von foo() die Größe des Zeigers zurück, nicht die Größe des Arrays. Auf den meisten Plattformen beträgt diese Größe typischerweise 4 Bytes in einem 32-Bit-System und 8 Bytes in einem 64-Bit-System, was der Grund ist, warum n in foo() nicht gleich 8 ist.

Der richtige Kontext in bar()

Im Gegensatz dazu wird cvalue innerhalb von bar() als lokales Array der Größe 8 definiert. Daher spiegelt sizeof(cvalue) hier korrekt die Größe des gesamten Arrays wider, was dazu führt, dass n gleich 8 ist.

Wichtige Erkenntnisse

  • Verständnis des Zeigerverhaltens: Wenn Sie Arrays als Parameter übergeben, übergeben Sie tatsächlich einen Zeiger, was zu irreführenden Werten bei der Benutzung von sizeof führen kann.
  • Lokale Arrays: sizeof gibt die tatsächliche Größe von lokal in einer Funktion definierten Arrays zurück und liefert das erwartete Ergebnis.
  • Syntaktischer Zucker: Die Klammern in Funktionsparametern erzeugen keine Array-Variablen, sondern zeigen an, dass Sie es mit einem Zeiger zu tun haben.

Fazit

Der Umgang mit Arrays in C und C++ kann knifflig sein, insbesondere für Neueinsteiger in die Sprache. Das Verständnis des Unterschieds zwischen Zeigern und Arrays ist entscheidend für korrekte Berechnungen und das Debuggen. Denken Sie daran, dass sizeof, das auf einen Parameter angewendet wird, der als Array angenommen wird, die Größe des Zeigers und nicht die Größe des Arrays zurückgibt, das Sie tatsächlich übergeben möchten.

Hoffentlich beleuchtet diese Erklärung das Verhalten des sizeof-Operators in Bezug auf Array-Argumente in Funktionen und klärt, warum n in der Funktion foo() nicht gleich 8 ist, jedoch in bar() schon. Behalten Sie diese Prinzipien im Hinterkopf, während Sie programmieren!