In which case the C++ this pointer can be NULL

2019-02-21 23:07发布

问题:

I experienced an issue that in the class constructor while I was using this pointer, but this pointer happen to be NULL at that time. for example

MyClass::MyClass()
{
   //this pointer happen to be NULL in this case, and it crash in teh m_callbackfunc because it does not handle null input.
   m_callbackFunc(this);
}

I wonder why this pointer can be null? and in which case this pointer can be null?

回答1:

The only way a this pointer can be NULL is if some code in the program has exhibited undefined behaviour.

It might for example be achieved by something like

  void *place = nullptr;
  MyClass *object = new (place) MyClass();

The problem is that this effectively dereferences a NULL pointer, so has undefined behaviour. So it is possible that MyClass constructor will have this as NULL. Any other effect is also possible - such is the nature of undefined behaviour.

Some debuggers also report this to be a NULL pointer. But that isn't actually a sign of this being NULL. It is a sign that this is a language keyword rather than something with a symbolic name in object files that the debugger can find. Some other debuggers, when asked to evaluate this simply report that nothing with that name exists in the current function/scope/whatever - possibly because the C++ compiler implements this by passing a value in a machine register.



回答2:

According to Visual Studio, I had this being a nullptr when I wrapped the object in a unique_ptr and didn't initialize it properly, then later on called a method on it to see what would happen.

While this differs from the opening post, it satisfies the topic title (assuming VS2015 wasn't lying to me).

This was due to me doing something wrong outside of the code (as others have alluded to elsewhere).



回答3:

was it a recursive function? If it was then yes, this can be null when the runtime stack runs out of space. this is pushed on to the stack. Try to re-write the function iteratively.

class Class
{
public:
    void makeThisNull();
};

void Class::makeThisNull()
{
    makeThisNull();
}
// run this in a debugger and you will see it crash when this == 0x0 (nullptr)
int main()
{
    Class c;
    c.makeThisNull();
    return 0;
}


回答4:

In which case the C++ this pointer can be NULL

this can be null if you call a class method through a null pointer.

SomeClass *a  = 0;
a->someMethod();//kaboom

While you definitely should NEVER be doing that, in practice you can even accientally get away with this without crashing (good luck catching that later) if someMethod doesn't access any object fields. (Just don't do that, alright?)

Whether it is defined behavior or not is a different subject altogether. Most likely it is undefined behavior.

However, that does not usually happen from within a constructor (I think I only saw null this in a constructor when something threw an exception in a constructor. That happened long ago, so I don't even remember details anymore). Which means something weird is going on. You could be trying to cast this to something, something might be corrupting stack, accessing program variables via different thread, and so on. With the mount of code you provided it is impossible to guess what the problem here is.