Alex Rivera | Logout

Accessing class members on a NULL pointer

Asked 2009-03-21T18:38:52.697
52

I was experimenting with C++ and found the below code as very strange.

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

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

int main(int argc, char** argv)
{
    Foo* foo = 0;
    foo->say_hi(); // works well
    foo->say_virtual_hi(); // will crash the app
    return 0;
}

I know that the virtual method call crashes because it requires a vtable lookup and can only work with valid objects.

I have the following questions

  1. How does the non virtual method say_hi work on a NULL pointer?
  2. Where does the object foo get allocated?

Any thoughts?

Edit
Report

1 Answer

6

It is undefined behaviour, but most compilers generate instructions which will handle this situation correctly if you access neither member variables nor the virtual table.

Let's see the disassembly generated by Visual Studio to understand what happens:

   Foo* foo = 0;
004114BE  mov         dword ptr [foo],0 
    foo->say_hi(); // works well
004114C5  mov         ecx,dword ptr [foo] 
004114C8  call        Foo::say_hi (411091h) 
    foo->say_virtual_hi(); // will crash the app
004114CD  mov         eax,dword ptr [foo] 
004114D0  mov         edx,dword ptr [eax] 
004114D2  mov         esi,esp 
004114D4  mov         ecx,dword ptr [foo] 
004114D7  mov         eax,dword ptr [edx] 
004114D9  call        eax  

As you can see Foo:say_hi is called as a normal function, but with this in the ecx register. To simplify you can assume that this is passed as implicit parameter, which is never used in your example.
But in the second case the address of the function must be calculated, due to the virtual table - this requires that the address of foo is valid and causes a crash.

answered 2009-03-21T19:00:08.387

Your Answer