开发者

Why doesn't the program crash when I call a member function through a null pointer in C++?

#include "iostream"
using namespace std;
class A
{
public:
    void mprint()
    {
        cout<<"\n TESTING NULL POINTER";
    }
};

int main()
{
    A *a = NULL;
    a->mprint();
    return 0;
}

I am getting output as "TESTING NULL P开发者_如何学PythonOINTER". Can anyone please explain why this program is printing the output instead of crashing. I checked it on Dev C++ and aCC compiler both gave same result.


You're not using any member variables of A - the function is completely independent of the A instance, and therefore the generated code happens to not contain anything that dereferences 0. This is still undefined behavior - it just may happen to work on some compilers. Undefined behavior means "anything can happen" - including that the program happens to work as the programmer expected.

If you e.g. make mprint virtual you may get a crash - or you may not get one if the compiler sees that it doesn't really need a vtable.

If you add a member variable to A and print this, you will get a crash.


According to the C++ spec, This program has undefined behavior because you're invoking a member function on a null receiver.

The reason that this works, though, is that non virtual member functions are typically implemented as regular functions that take the "this" pointer as an implicit first argument. Consequently, if you call a member function on a null pointer, as long as you don't use the this pointer, your program will not crash. Of course, you cannot rely n this; a valid C++ compiler could cause this to crash.

However, virtual functions are a different story because the function that actually gets called needs to be resolved at runtime. This usually involves introspecting on the receiver's virtual function table. Thus if you try calling a virtual member function on a null pointer, even if te function doesn't access this, it will still cause a crash. Try this out if you're curious!


The results of calling a member function using a null pointer to an object is undefined behavour in c++ so it can do anything.

In this case it's likely because it's rewritten your function as it it was like this

void mprint(A* this);

and your call like this

mprint(0);

So it's just called it as if it was an ordinary function and passed the null pointer as a parameter which you never then actually use in any way. That explains why it doesn't crash, but the compiler is free to do pretty much anything


Simple Answer: Because mprint() is not using any of the member variables of the class

Detailed Answer: When a method of a class is called, class instance is passed on to the callee function (normally as the first argument, however, in some calling conventions such as __thiscall, this is passed in a register). This class instance is used to access all the member variables that are used in the callee method.

In this case, this instance is NULL but this doesnt make any difference since no member variables are being used in the callee method. Try changing your code such that you print the value of a member variable in mprint() method and you will get the crash.


Being able of invoking non-virtual member functions on non-valid pointers even enables encoding the information associated to an object in the pointer itself. For example:

#include <iostream>

class MagicInteger {

  public:

   static MagicInteger* fromInt (int x) {
     return reinterpret_cast<MagicInteger*>(x);
   }

   int getValue() {
     return static_cast<int>(reinterpret_cast<intptr_t>(this));
   }       

  private:
   // forbid messing around
   MagicInteger ();  
   MagicInteger (MagicInteger&);
   MagicInteger& operator=(const MagicInteger&);
};

int main (void) {
  MagicInteger* i = MagicInteger::fromInt(6);
  std::cout << "Value is " << i->getValue() << std::endl;
  return 0;
}

This can also be used to implement tagged pointers, that is, pointers that contain meta-information about the pointee.

These two idioms are used in Google Chrome's javascript VM V8 to represent 31-bit integers


This is completely legal call.

lets understand how it works

when a new object is creates its member variables are created.

What about member functions? Member function are not allocated news there is always one copy of all member function. By default a member variable is added to every member function that is this pointer which is pointing to the object itself.
When there is no object present that is object pointer is null value. It doenst matter because you are not accesssing it any way. You will get in problems if you use this pointer of any of the member variable in the method. This is because member variable are not valid in case of null pointer.

in MFC we have GetSafeHwnd() method for CWnd. This works on same principle.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜