For C++, when we check whether the pointer is valid or not, usually we do the following:
if (p == NULL){
// error handling
}
However, in VC++, even p is not NULL (aka 0), it is 0x00000004, also means Bad Ptr. and then cause exception, we know this address is protected, can not be overwritten.
I have searched similar questions here, but I did not get the answer.
My questions are:
- when the Bad Ptr happened, why not just set this pointer to 0?
- since the value of Bad Ptr is not zero, how to check whether the pointer is valid or not in VC++?
In Windows, the first 65536 bytes in the virtual memory address space (addresses 0x00000000 through 0x0000FFFF) are always unmapped, never being able to address RAM. A feature that ensures that bad pointer values always crashes the program with an AccessViolation. Most commonly because of a NULL pointer, but null pointers don't exclusively produce accesses to address 0. In an object-oriented programming language like C++ for example, trying to access a member of a object through a null pointer generates accesses to addresses larger than 0. Larger by the offset of the member inside the object.
That's not where the debugger stops, you will also see Bad Ptr on other addresses, the kind that reference unmapped memory pages. And, if dereferenced, will crash your program as well. A good reason to start using a debugger. But not your case, 0x00000004 is already covered by the exclusion zone at the bottom.
The winapi has functions to test whether a pointer value is bad. I'm not going to document them though, these functions are dangerous.
Having a pointer value like that is always a bug in your code. You must fix the bug.
- Bad Ptr does not means
0
always, it means the pointer is invalid (either the address is invalid like containing garbage, or address is valid but does not belong to your program etc.). 0
or NULL
is a special case.
You should always initialize a pointer when declaring it, either with valid address or nullptr
. Then you can check if(p==nullptr)
before using it.
For example
int* p = reinterpret_cast<int*>(100);
Here p
is not NULL
, but it points to an invalid address.