|
Archives
D Programming
D
D.gnu
digitalmars.D
digitalmars.D.bugs
digitalmars.D.dtl
digitalmars.D.dwt
digitalmars.D.announce
digitalmars.D.learn
digitalmars.D.debugger
C/C++ Programming
c++
c++.announce
c++.atl
c++.beta
c++.chat
c++.command-line
c++.dos
c++.dos.16-bits
c++.dos.32-bits
c++.idde
c++.mfc
c++.rtl
c++.stl
c++.stl.hp
c++.stl.port
c++.stl.sgi
c++.stlsoft
c++.windows
c++.windows.16-bits
c++.windows.32-bits
c++.wxwindows
digitalmars.empire
digitalmars.DMDScript
|
c++ - cann't throw exception
↑ ↓ ← → "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
↑ ↓ ← → "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
↑ ↓ ← → 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
↑ ↓ ← → "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.
↑ ↓ ← → "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.
↑ ↓ ← → "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
reference generates an exception, and if there are any copies
it, they will generate an exception anytime a member function call is
attempted.
↑ ↓ ← → "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
"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
reference is set to NULL. This means that accessing the object through
reference generates an exception, and if there are any copies
it, they will generate an exception anytime a member function call is
attempted.
↑ ↓ ← → "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
"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
reference is set to NULL. This means that accessing the object
the
reference generates an exception, and if there are any copies
it, they will generate an exception anytime a member function call
attempted.
↑ ↓ ← → "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
"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
reference is set to NULL. This means that accessing the object
the
reference generates an exception, and if there are any copies
it, they will generate an exception anytime a member function call
attempted.
↑ ↓ ← → 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.
↑ ↓ ← → "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>.
↑ ↓ ← → 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
|
|