Debugging null objects
Jan 13, 2010 at 4:23pm UTC
I was wondering if there's a language-level construct or gcc directive to accomplish the following effect:
class foo {
public:
void DoSomething(void);
};
...
foo *f = 0L;
if (f) f->DoSomething(); // bug: f is null
What I'd like to do is be able to call f->DoSomething with impunity and have a null object trap to a custom debug routine.
Example:
class foo {
public:
void DoSomething(void) {};
void CustomTrap(void) {
printf("DoSomething was invoked from a null object\n");
exit;
};
};
...
foo *f = 0L;
f->DoSomething();
would then cause CustomTrap to be executed.
Even feasible?
Jan 13, 2010 at 4:28pm UTC
NULL is not an object, is the value you assign to a pointer to know that it's pointing to nothing
Jan 13, 2010 at 4:35pm UTC
The only way to do something sort of like that would be to check in each member function the validity of
this
:
1 2 3 4 5
void DoSomething(){
if (!this )
this ->CustomTrap();
//...
}
Jan 13, 2010 at 5:49pm UTC
Helios...
That should cause a segmenation fault because this = 0.
What the user is asking is not possible that I am aware of.
Jan 13, 2010 at 6:14pm UTC
Look at the header <memory> at auto_ptr.
It implements operator-> and shows you exactly how to do it.
Of course it means that you won't be able to have a foo* directly;
rather, you'll need to instantiate a proxy object that contains a foo*.
Jan 13, 2010 at 6:27pm UTC
Yes the auto_ptr would solve the issue as its not a pointer, rather it exists on the heap and contains reference to the assigned pointer. Thus the auto_ptr itself cannot be NULL.
The auto_ptr class could be overloaded with the DoSomething() method to give the defined method.
I.e.
1 2 3 4 5 6 7 8 9 10
void DoSomething()
{
if (NULL != this ->get())
{
this ->get()->DoSomething();
return ;
}
// do something else when not allocated
}
However you have to change the method calling the auto_ptr from:
obj->DoSomething();
to
obj.DoSomething()
Since the auto_ptr already has the "operator ->" defined to utilize the internal object. And in my example you need to call the auto_ptr itself which determines which functionality to use.
Last edited on Jan 13, 2010 at 6:32pm UTC
Jan 13, 2010 at 11:15pm UTC
That should cause a segmenation fault
It won't.
Jan 14, 2010 at 3:10pm UTC
Something like this may work in a pinch:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
template <typename T>
struct MyAutoPtr : public std::auto_ptr<T>
{
T* operator ->() const
{
T* const p = this ->get();
if (p == 0)
T::CustomTrap(); // must not return.
return p;
}
};
MyAutoPtr<Foo> foo;
foo->doSomething();
Note that CustomTrap() has to be a static method.
Note also that exiting from a C++ application is very bad form as some destructors may not get called. A C++ program should always return from main().
A better option may be to throw a logic_error (or an exception derived from logic_error) in operator->() and catch that exception, possibly in main().
Topic archived. No new replies allowed.