www.digitalmars.com         C & C++   DMDScript  

c++ - cann't throw exception

reply "Neo" <newneo2 yahoo.com> writes:
hi
i am using try catch mechanism to check validity of pointers

i have some class called X and i matrying to exe. this
class X{
public;
    bool valid();
};


{
X *x= new X;
delete x;
try{
    if(x->Valid()){...}
    cout<<"i have reached here(Problem)";
}
catch(...){
    cout<<"Trying to access invalid object";
}
}

i want something like if x is deleted it should raise exception. i cann't
assign NULL after deleting that object, that object will be having some
value, it may be valid or invalid but surlly not NULL

pls if possible tell me other workout solution or bug in this code
Nov 27 2002
next sibling parent "Walter" <walter digitalmars.com> writes:
Deleting an object doesn't necessarilly set its contents to any arbitrary
values that might cause an exception if accessed.

-Walter

"Neo" <newneo2 yahoo.com> wrote in message
news:as21fj$27v0$1 digitaldaemon.com...
 hi
 i am using try catch mechanism to check validity of pointers

 i have some class called X and i matrying to exe. this
 class X{
 public;
     bool valid();
 };


 {
 X *x= new X;
 delete x;
 try{
     if(x->Valid()){...}
     cout<<"i have reached here(Problem)";
 }
 catch(...){
     cout<<"Trying to access invalid object";
 }
 }

 i want something like if x is deleted it should raise exception. i cann't
 assign NULL after deleting that object, that object will be having some
 value, it may be valid or invalid but surlly not NULL

 pls if possible tell me other workout solution or bug in this code
Nov 27 2002
prev sibling parent reply Laurentiu Pancescu <plaur crosswinds.net> writes:
One solution:

class X
{
   bool deleted_;
public:
   X() : deleted_(false) {}
   virtual ~X() { deleted_ = true; }
   bool valid() {
     if (deleted_) throw WhateverGoodNameYouCanThinkOf();
     return true; }
};

You can even derive from X (multiple inheritance might result from 
here), and you need to make sure that every method is calling the 
X::valid() - not good, if other people can derive from your classes, 
since this is not enforced by compiler, as with constructors/destructors.

Second solution:

In C++ User's Journal, a few months ago, it was a very interesting 
article "Debugging Memory Leaks".  The idea will change a little bit 
in your case: you'll still use a custom memory allocator (you still 
need page granularity for memory protection to work), but you set the 
memory access to PAGE_NO_ACCESS (or whatever it's called in Win32 
API), in the destructor.  It's a beautiful solution, work even with 
STL-derived classes, and everything!  The advantage is that the 
existing code doesn't need to be modified, and any access to a deleted 
object will trigger a processor exception, easy to catch with the 
debugger, and then you just have to go up in the stack trace, to find 
the bad guy.

Third solution, probably best:

Rethink your object lifetime design.

HTH,
   Laurentiu

P.S.  I would be very interested to hear about other possible 
solutions to this particular problem.


Neo wrote:
 hi
 i am using try catch mechanism to check validity of pointers
 
 i have some class called X and i matrying to exe. this
 class X{
 public;
     bool valid();
 };
 
 
 {
 X *x= new X;
 delete x;
 try{
     if(x->Valid()){...}
     cout<<"i have reached here(Problem)";
 }
 catch(...){
     cout<<"Trying to access invalid object";
 }
 }
 
 i want something like if x is deleted it should raise exception. i cann't
 assign NULL after deleting that object, that object will be having some
 value, it may be valid or invalid but surlly not NULL
 
 pls if possible tell me other workout solution or bug in this code
 
 
 
 
Nov 27 2002
next sibling parent reply "Walter" <walter digitalmars.com> writes:
"Laurentiu Pancescu" <plaur crosswinds.net> wrote in message
news:as36h0$m0j$1 digitaldaemon.com...
 P.S.  I would be very interested to hear about other possible
 solutions to this particular problem.
In D, whenever an object gets deleted, it's vptr is set to NULL and the reference is set to NULL. This means that accessing the object through the reference generates an exception, and if there are any copies referencing it, they will generate an exception anytime a member function call is attempted.
Nov 27 2002
next sibling parent reply "Matthew Wilson" <dmd synesis.com.au> writes:
Is that something that could be added to DMC++ (via an option, of course)?

"Walter" <walter digitalmars.com> wrote in message
news:as3gip$10q8$1 digitaldaemon.com...
 "Laurentiu Pancescu" <plaur crosswinds.net> wrote in message
 news:as36h0$m0j$1 digitaldaemon.com...
 P.S.  I would be very interested to hear about other possible
 solutions to this particular problem.
In D, whenever an object gets deleted, it's vptr is set to NULL and the reference is set to NULL. This means that accessing the object through the reference generates an exception, and if there are any copies referencing it, they will generate an exception anytime a member function call is attempted.
Nov 27 2002
parent reply "Walter" <walter digitalmars.com> writes:
Yes.

"Matthew Wilson" <dmd synesis.com.au> wrote in message
news:as3l25$15pt$1 digitaldaemon.com...
 Is that something that could be added to DMC++ (via an option, of course)?

 "Walter" <walter digitalmars.com> wrote in message
 news:as3gip$10q8$1 digitaldaemon.com...
 "Laurentiu Pancescu" <plaur crosswinds.net> wrote in message
 news:as36h0$m0j$1 digitaldaemon.com...
 P.S.  I would be very interested to hear about other possible
 solutions to this particular problem.
In D, whenever an object gets deleted, it's vptr is set to NULL and the reference is set to NULL. This means that accessing the object through
the
 reference generates an exception, and if there are any copies
referencing
 it, they will generate an exception anytime a member function call is
 attempted.
Nov 27 2002
parent reply "Matthew Wilson" <dmd synesis.com.au> writes:
Cool. When can we have it? Obviously it'll have to be after Mr Access
Violation is vanquished ... ;)


"Walter" <walter digitalmars.com> wrote in message
news:as405q$1guh$1 digitaldaemon.com...
 Yes.

 "Matthew Wilson" <dmd synesis.com.au> wrote in message
 news:as3l25$15pt$1 digitaldaemon.com...
 Is that something that could be added to DMC++ (via an option, of
course)?
 "Walter" <walter digitalmars.com> wrote in message
 news:as3gip$10q8$1 digitaldaemon.com...
 "Laurentiu Pancescu" <plaur crosswinds.net> wrote in message
 news:as36h0$m0j$1 digitaldaemon.com...
 P.S.  I would be very interested to hear about other possible
 solutions to this particular problem.
In D, whenever an object gets deleted, it's vptr is set to NULL and
the
 reference is set to NULL. This means that accessing the object through
the
 reference generates an exception, and if there are any copies
referencing
 it, they will generate an exception anytime a member function call is
 attempted.
Nov 27 2002
next sibling parent "Walter" <walter digitalmars.com> writes:
It'll have to wait, there are a lot of other things to do first :-(

"Matthew Wilson" <dmd synesis.com.au> wrote in message
news:as44eq$1l9n$1 digitaldaemon.com...
 Cool. When can we have it? Obviously it'll have to be after Mr Access
 Violation is vanquished ... ;)


 "Walter" <walter digitalmars.com> wrote in message
 news:as405q$1guh$1 digitaldaemon.com...
 Yes.

 "Matthew Wilson" <dmd synesis.com.au> wrote in message
 news:as3l25$15pt$1 digitaldaemon.com...
 Is that something that could be added to DMC++ (via an option, of
course)?
 "Walter" <walter digitalmars.com> wrote in message
 news:as3gip$10q8$1 digitaldaemon.com...
 "Laurentiu Pancescu" <plaur crosswinds.net> wrote in message
 news:as36h0$m0j$1 digitaldaemon.com...
 P.S.  I would be very interested to hear about other possible
 solutions to this particular problem.
In D, whenever an object gets deleted, it's vptr is set to NULL and
the
 reference is set to NULL. This means that accessing the object
through
 the
 reference generates an exception, and if there are any copies
referencing
 it, they will generate an exception anytime a member function call
is
 attempted.
Nov 28 2002
prev sibling parent "Walter" <walter digitalmars.com> writes:
Once I had a feature in the runtime library where it would issue an error if
you tried to free() the same pointer twice. You would not believe the
continuous stream of bug reports I'd get saying that their program "worked"
with Brand X compiler and I needed to fix the "bug" in mine.

One more reason why garbage collection is where the future lies <g>.

"Matthew Wilson" <dmd synesis.com.au> wrote in message
news:as44eq$1l9n$1 digitaldaemon.com...
 Cool. When can we have it? Obviously it'll have to be after Mr Access
 Violation is vanquished ... ;)


 "Walter" <walter digitalmars.com> wrote in message
 news:as405q$1guh$1 digitaldaemon.com...
 Yes.

 "Matthew Wilson" <dmd synesis.com.au> wrote in message
 news:as3l25$15pt$1 digitaldaemon.com...
 Is that something that could be added to DMC++ (via an option, of
course)?
 "Walter" <walter digitalmars.com> wrote in message
 news:as3gip$10q8$1 digitaldaemon.com...
 "Laurentiu Pancescu" <plaur crosswinds.net> wrote in message
 news:as36h0$m0j$1 digitaldaemon.com...
 P.S.  I would be very interested to hear about other possible
 solutions to this particular problem.
In D, whenever an object gets deleted, it's vptr is set to NULL and
the
 reference is set to NULL. This means that accessing the object
through
 the
 reference generates an exception, and if there are any copies
referencing
 it, they will generate an exception anytime a member function call
is
 attempted.
Nov 28 2002
prev sibling parent reply Laurentiu Pancescu <plaur crosswinds.net> writes:
This means that D uses only late binding, just like Java, right? 
Otherwise, this wouldn't affect non-virtual methods...

Laurentiu

Walter wrote:
 "Laurentiu Pancescu" <plaur crosswinds.net> wrote in message
 news:as36h0$m0j$1 digitaldaemon.com...
 
P.S.  I would be very interested to hear about other possible
solutions to this particular problem.
In D, whenever an object gets deleted, it's vptr is set to NULL and the reference is set to NULL. This means that accessing the object through the reference generates an exception, and if there are any copies referencing it, they will generate an exception anytime a member function call is attempted.
Nov 28 2002
parent "Walter" <walter digitalmars.com> writes:
"Laurentiu Pancescu" <plaur crosswinds.net> wrote in message
news:as5qg9$ean$1 digitaldaemon.com...
 This means that D uses only late binding, just like Java, right?
 Otherwise, this wouldn't affect non-virtual methods...
That's correct. It isn't perfect, just better. Also, the gc won't delete things that still have references to them, this technique only applies when objects are manually deleted. I've switched all my own new code, even my C++ code, to using GC. It saves a lot of programming time <g>.
Nov 28 2002
prev sibling parent Richard <fractal clark.net> writes:
In article <as36h0$m0j$1 digitaldaemon.com>, Laurentiu Pancescu says...
One solution:

class X
{
   bool deleted_;
public:
   X() : deleted_(false) {}
   virtual ~X() { deleted_ = true; }
   bool valid() {
     if (deleted_) throw WhateverGoodNameYouCanThinkOf();
     return true; }
};
mm.. this seems very dangerous. Since any attempt to access the Valid() member through an invalid pointer is undefined. It might not work at all, it might work until you add some more code to the module, or get a kernel patch, or just about anything.. it might work for 10 minutes, 2 days, or even three years.. and then bang.
Second solution:
This is a very good solution for windows platform.
Third solution, probably best:

Rethink your object lifetime design.
Yes, rethink. Perhaps use surrogate class with associated resource / usecnt object that points to an actual object (the X class in the original poster's example). See the first few chapters of "Ruminitions on C++" for a description of Handles. Also, I think latest edition of Stroustrup's "The C++ Programming Language", talks about resource handling. In any case, with Handles, you can add a destroy method to the Handle class that destroys the object pointed to by the resource object, and marks the resource object as invalid. Handle member conversion operators to reference or pointer of the real class (again the X class) can check the validity of the resource, and throw exceptions to your try block. I tend to use a Handle template and resource allocate through it. This is also effective for use in STL containers that expect cc'tor on insertion (except for any containers like vector with its nasty unitialized_copy). Using a handle, an STL container like list can be tied to the object and when the container goes out of scope, so do the objects. Here's a brief example using the original poster's example. If you find a bug, let me know so I can fix my Handle template! #include <iostream> struct X { }; struct X_Resource { friend struct X_Handle; X_Resource(X* x) : usecnt(1), obj(x) { } ~X_Resource() { delete obj; } X* obj; int usecnt; }; struct X_Handle { X_Resource* r; X_Handle(X* x) { r = new X_Resource(x); } X_Handle(const X_Handle& h) { r = h.r; r->usecnt++; } X_Handle& operator=(X_Handle& h) { if (this != &h) { r->usecnt--; if (r->usecnt == 0) delete r; r = h.r; r->usecnt++; } return *this; } operator X&() throw (int) { X* obj = r->obj; if (obj == 0) throw int(1); return *obj; } ~X_Handle() { r->usecnt--; if (r->usecnt == 0) delete r; } void destroy() { X* obj = r->obj; delete obj; r->obj = 0; } }; main() { X_Handle x(new X); x.destroy(); try{ X& test = x; cout<<"i have reached here(Problem)"; } catch(...){ cout<<"Trying to access invalid object"; } } Richard
Nov 29 2002