Heim >Backend-Entwicklung >C++ >Warum funktioniert der Aufruf einer nicht virtuellen Memberfunktion auf einem Nullzeiger in C manchmal?

Warum funktioniert der Aufruf einer nicht virtuellen Memberfunktion auf einem Nullzeiger in C manchmal?

DDD
DDDOriginal
2024-12-13 16:58:10660Durchsuche

Why Does Calling a Non-Virtual Member Function on a Null Pointer in C   Sometimes Work?

Gotcha in C: Zugriff auf nicht-virtuelle Klassenmitglieder auf einem Nullzeiger

Aufruf von nicht-virtuellen Mitgliedsfunktionen in C auf einer Null Der Zeiger funktioniert möglicherweise unerwartet und wirft ein merkwürdiges Rätsel auf. Lassen Sie uns dieses Verhalten anhand eines faszinierenden Codeausschnitts untersuchen:

class Foo {
public:
    virtual void say_virtual_hi() {
        std::cout << "Virtual Hi";
    }

    void say_hi() {
        std::cout << "Hi";
    }
};

int main() {
    Foo* foo = 0;
    foo->say_hi(); // Works well
    foo->say_virtual_hi(); // Crashes the app
    return 0;
}

Rätsel erklärt

Die Verwirrung entsteht durch die unterschiedlichen Mechanismen, die zum Aufrufen virtueller und nicht virtueller Methoden verwendet werden .

  • Virtuelle Methoden: Erforderlich Vtable-Suche, um die aufzurufende Funktion zu bestimmen, was bei Nullzeigern fehlschlägt, da ihnen keine gültigen Objekte zugeordnet sind.
  • Nicht-virtuelle Methoden: Werden direkt als Funktionsaufruf mit kompiliert Dieser Zeiger (Objektreferenz) wird als versteckter Parameter übergeben.

Im angegebenen Code wird die nicht-virtuelle Methode say_hi() niemals explizit verwendet dereferenziert den this-Zeiger und umgeht den Nullzeiger-Dereferenzierungsfehler. Es ist im Wesentlichen das Äquivalent eines Funktionsaufrufs mit einem Parameter, der als Wert übergeben wird:

void Foo_say_hi(Foo* this);

Foo_say_hi(foo);

Undefiniertes Verhalten

Technisch gesehen ist der Aufruf einer beliebigen Funktion (auch einer nicht virtuellen) möglich Ein Nullzeiger ist ein undefiniertes Verhalten in C. Einige Compiler-Implementierungen können jedoch ein klar definiertes Verhalten für bestimmte Szenarien bereitstellen, wie z. B. den oben genannten nicht-virtuellen Funktionsaufruf.

Achtung

Während das unerwartete Verhalten auftreten kann bequem, sich darauf zu verlassen ist riskant und keine bewährte Vorgehensweise. Vermeiden Sie immer den Zugriff auf Klassenmitglieder mit Nullzeigern, da dies zu unerwarteten und unvorhersehbaren Ergebnissen führen kann.

Das obige ist der detaillierte Inhalt vonWarum funktioniert der Aufruf einer nicht virtuellen Memberfunktion auf einem Nullzeiger in C manchmal?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn