Frage Was passiert, wenn ich eine Memberfunktion für einen NULL-Objektzeiger aufruft?


Mir wurde folgendes als Interviewfrage gegeben:

class A
{
public:
    void fun()
    {
        std::cout << "fun" << std::endl;
    }
};

A* a = NULL;
a->fun();

Was passiert, wenn dieser Code ausgeführt wird und warum?


Siehe auch:


36
2018-03-28 15:46


Ursprung


Antworten:


Es ist undefiniertes Verhalten, also könnte alles passieren.

Ein mögliches Ergebnis wäre, dass es nur druckt "fun" da die Methode nicht auf Mitgliedsvariablen des Objekts zugreift, an dem sie aufgerufen wird (der Speicher, in dem das Objekt angeblich lebt, muss nicht aufgerufen werden, so dass Zugriffsverletzungen nicht notwendigerweise auftreten).


54
2018-03-28 15:53



Nach dem Standard ist dies undefiniertes Verhalten und daher eine sehr schlechte Sache. In der Realität der meisten Programmierplattformen (sowohl für X86 als auch für mehrere andere Architekturen) wird dies gut funktionieren.

Warum? Überlegen Sie, wie Klassenfunktionen in C ++ implementiert werden. Dies ist keine virtuelle Funktion, daher kann dies ein statischer Aufruf einer bekannten Adresse sein. In x86 Assembly können wir dies als sehen

mov A, 0
mov ecx, A
call a__fun

Da a__fun keine Instanzdaten benötigt, wird nichts passieren, obwohl es einen Null-Zeiger empfängt.

Immer noch beschissener Code und jeder Compiler wird schreien, aber es kann laufen.


20
2018-03-28 17:23



Das wahrscheinlichste Verhalten auf den meisten modernen Computern ist, dass es läuft und "Spaß" ausdruckt, weil:

  • C ++ überprüft vor Aufruf der Funktion nicht, ob der Zeiger NULL ist
  • fun() ist nicht virtuell, daher muss nicht auf eine vtable verwiesen werden, die aufgerufen werden soll fun()
  • fun() Zugriff auf keine Mitgliedsvariablen in A es muss also nicht dereferenziert werden die Null this Zeiger.

12
2018-03-28 15:49



Wir können nicht wissen was werden. Alles kann passieren, weil das Programm undefiniertes Verhalten aufdeckt. Sehen Führt das Aufrufen einer Memberfunktion für eine Nullinstanz zu einem undefinierten Verhalten?.


9
2018-03-28 15:48



Ich habe mehrere Male versucht, die ganze Zeit kommt "Spaß" das ist, weil Funktion fun ist unabhängig von der Instanz a. beim Anrufen a->fun();  a zeigt auf 0, das ist ein undefiniertes Verhalten, aber in den meisten Compilern sollte es keinen Absturz geben.


6
2017-10-24 04:29



Drei Punkte könnten helfen:

1) Alle Funktionen sind im Code- oder Textbereich gespeichert.

2) Nicht-virtuelle Funktionen werden zum Zeitpunkt der Komplettierung aufgelöst.

3) Beim Aufruf von Member-Funktionen der Klasse übergeben wir das aktuelle Objekt als this Zeiger auf diese Funktion.

Komm zu deiner Frage, hier fun() Funktion ist bereits im Speicher (Codeabschnitt / Textabschnitt). Als Funktion fun() ist nicht virtuell, wird zur Complie-Zeit aufgelöst (d. h. für diese Zeile springt es zu der Instruktion X im Code-Abschnitt mit this Zeiger als NULL). Da keine Member-Variable und keine virtuelle Funktion verwendet / aufgerufen wird fun() Funktion, es funktioniert gut.


0
2018-05-17 14:45