Dereferencing a null pointer is undefined behavior. Undefined behavior is not equal to error. Anything may happen if you triggered undefined behavior. If you are asking the other way:
Why is undefined behavior not causing an error instead of giving us strange behavior?
It may be due to many reason. One reason is performance. For example, in the implementation of std::vector
(at least in MSVC), there is no check if the index is out of range in Release Mode. You can try to do this:
std::vector<int> v(4);
v[4]=0;
It will compile and run. You may got strange behavior or you may not. However, in Debug mode it will throw exception at run-time. MSVC does the check in Debug Mode because performance is not important in Debug Mode. But it does not in Release Mode because performance matters.
The same applies for dereferencing a null pointer. You can image that the code of dereferencing will be put in a wrapper like this:
//Imaginary code
T& dereference(T* ptr){
if(ptr==nullptr){
throw;
}
return *ptr;
}
This part: if(ptr==nullptr){throw;}
will slow the dereferencing process of every pointer in the context which is not desirable.
However, it may be done like this:
//Imaginary code
T& dereference(T* ptr){
#ifdef DEBUG
if(ptr==nullptr){
throw;
}
#endif
return *ptr;
}
I think you got the idea now.