In this answer to this question, it was noted that:
If you're going to 'clear' the pointer in the dtor, a different idiom would be better - set the pointer to a known bad pointer value.
and also that the destructor should be:
~Foo() { delete bar; if (DEBUG) bar = (bar_type*)(long_ptr)(0xDEADBEEF); }
I have two question about these parts of the answer.
Firstly, how can you set the pointer to a known bad pointer value? How can you set a pointer to an address which you can assure won't be allocated?
Secondly, what does: if (DEBUG) bar = (bar_type*)(long_ptr)(0xDEADBEEF);
even do? What's DEBUG
? I couldn't find a macro named so. Also, what's long_ptr
? What does it do?
how can you set the pointer to a known bad pointer value? How can you set a pointer to an address which you can assure won't be allocated?
First, let me be clear that the example code you refer to is a dirty hack and is intended to provide some guidance to assist debugging. It is not intended as a production quality memory management tool; it isn't even intended to be "drop in" code - it's an example of a debugging technique.
Setting a pointer to a hardcoded value isn't guaranteed to be a "bad pointer" unless you know something about the target environment. 0xDEADBEEF
is a value that is likely to be an invalid pointer on many environments just out of luck. The value was chosen in because I had seen it used as a marker for "invalid data" in other code and it is easily spotted when viewing memory dumps. I believe it is (or was, maybe not anymore - that answer was from 14 years ago!) commonly used to indicate memory areas that are invalid/unused. Similar to some of the values Microsoft used in their debug library versions of some memory management routines (see https://stackoverflow.com/a/370362)
what does:
if (DEBUG) bar = (bar_type*)(long_ptr)(0xDEADBEEF);
even do? What'sDEBUG
? I couldn't find a macro named so.
I might not have said explicitly in the answer you refer to, but the example code might more properly be call a pseudo-code example. if (DEBUG)
is used to indicate a bit of code that is conditionally executed "if this is a debug build".
For example, DEBUG
could be a macro (or variable) that is defined as non-zero during a debug build of the problem. Possibly on the compiler's command line (maybe something like -DDEBUG=1
). A DEBUG
macro is something that I found commonly used for code that is enabled in debug builds only.
Also, what's
long_ptr
? What does it do?
To aid in the transition from 32-bit to 64-bit systems, MS added types that are size of pointers. LONG_PTR
is an integer type that has the size of a pointer (32 or 64 bits as appropriate). I probably should have used LONG_PTR
instead of long_ptr
. I believe the cast is technically unnecessary, but I think it's still useful as a notation that makes clear that an integer is being 'converted' to a pointer - a coding idiom that uses dirty looking casts to call out a dirty hack.