Board index » cppbuilder » Another Casting question

Another Casting question


2004-01-10 01:38:22 PM
cppbuilder17
class B
{
C();
virtual ~C();
};
class D : public B
{
};
C* ptrB = new B();
delete ptrB;
D* ptrD = dynamic_cast<D*>(ptrB);
This last line has a problem because ptrB was already deleted.
I get "Assertion failed: ((unsigned __far *)vtablePtr[-1] == 0, file
xxtype.cpp, line 1099
xxtype.cpp is no file of mine.
try catch does not fix the problem is there any way around this
error...other than the obvious don't delete ptrB before hand :)
I'm using a TServerSocket with type stNonBlocking. On a client connect I'm
saving the TCustomWinSocket* of the client for easy access. I don't ever
delete this pointer since I assume its the responsibility of the
TServerSocket to handle all of that. I do set my stored pointer of the
TCustomWinSocket to NULL when a client disconnects via the
OnClientDisconnect.
I'm getting an AccessViolationError when using the SendBuffer method of the
TCustomWinSocket. I know its not the buffer I'm passing in so I'm assuming
the pointer to TCustomWinSocket somehow is invalid whether it was deleted by
the TServerSocket I don't know.
I'm not actually using the dynamic_cast for the TCustomWinSocket but I'm
looking for a way to determine if it is still valid or if it has been
deleted. Only thing I can come up with is that TServerSocket is deleting
the TCustomWinSocket and not first notifying me with an OnClientDissconnect.
Any ideas?
 
 

Re:Another Casting question

"JunkMail" < XXXX@XXXXX.COM >writes:
Quote
class B
{
C();
virtual ~C();
};
This is invalid. Do you mean B or C?
Quote
class D : public B
{
};

C* ptrB = new B();
What is C*?
Quote
delete ptrB;
D* ptrD = dynamic_cast<D*>(ptrB);
This last line has a problem because ptrB was already deleted.
Using an invalid pointer is invalid, yes.
Quote
I get "Assertion failed: ((unsigned __far *)vtablePtr[-1] == 0, file
xxtype.cpp, line 1099

xxtype.cpp is no file of mine.
You confused the compiler and triggered an internal bug. However, I'm
confused too, since your code shouldn't even compile. :)
Quote
try catch does not fix the problem is there any way around this
error...other than the obvious don't delete ptrB before hand :)
Right. try...catch never fixes, corrects, or handles bugs in your
program. It does nothing but catch exceptions that are rasied by your
own code when you explicitly throw an exception. (Or you call into
code that throws one for you.)
Quote
I'm not actually using the dynamic_cast for the TCustomWinSocket but I'm
looking for a way to determine if it is still valid or if it has been
deleted. Only thing I can come up with is that TServerSocket is deleting
the TCustomWinSocket and not first notifying me with an OnClientDissconnect.
The only way to test for a pointer being valid is to check it against
being null. That also means that if you delete a pointer, and you
later plan to "check" if it's valid, it's up to you to SET it to null
immediately after deleting it. Otherwise, it is _impossible_ to
detect (and only your careful programming can ensure you don't use it.)
--
Chris (TeamB);
 

Re:Another Casting question

Boy I really screwed up that example...the text below the example doesn't
pertain to the example so I'll just repost the example.
class B
{
B();
virtual ~B();
};
class D : public B
{
D();
virtual ~D();
};
B* ptrB = new B();
delete ptrB;
D* ptrD = dynamic_cast<D*>(ptrB);
This last line has a problem because ptrB was already deleted.
 

{smallsort}

Re:Another Casting question

"JunkMail" < XXXX@XXXXX.COM >wrote in message
Quote
C* ptrB = new B();
You can't do that. B is not derived from C, so you can't assign an instance
of B to a C pointer. Perhaps you meant D instead?
Quote
D* ptrD = dynamic_cast<D*>(ptrB);
This last line has a problem because ptrB was already deleted.
Correct. You are trying to access invalid memory. Casting does not check
the validity of memory, only the existance of the necessaty vtable info.
Quote
I get "Assertion failed: ((unsigned __far *)vtablePtr[-1] == 0,
file xxtype.cpp, line 1099

xxtype.cpp is no file of mine.
It is an internal source file used by Borland.
Quote
is there any way around this error...other than the obvious
don't delete ptrB before hand :)
Not that I am aware of.
Quote
I don't ever delete this pointer since I assume its the
responsibility of the TServerSocket to handle all of that.
Correct.
Quote
I'm getting an AccessViolationError when using the SendBuffer method
of the TCustomWinSocket. I know its not the buffer I'm passing in so
I'm assuming the pointer to TCustomWinSocket somehow is invalid
whether it was deleted by the TServerSocket I don't know.
Doubtful. The socket pointer is still valid when the OnDisconnect event is
triggered. You should not be trying to send data when the socket is in the
process of disconnecting, however.
Quote
I'm not actually using the dynamic_cast for the TCustomWinSocket
but I'm looking for a way to determine if it is still valid or if it has
been
deleted.
There is no way to determine that programmably in a reliable fashion.
Quote
Only thing I can come up with is that TServerSocket is deleting the
TCustomWinSocket and not first notifying me with an OnClientDissconnect.
No, that is not the case.
Gambit
 

Re:Another Casting question

Quote
>I'm not actually using the dynamic_cast for the TCustomWinSocket but I'm
>looking for a way to determine if it is still valid or if it has been
>deleted. Only thing I can come up with is that TServerSocket is
deleting
>the TCustomWinSocket and not first notifying me with an
OnClientDissconnect.

The only way to test for a pointer being valid is to check it against
being null. That also means that if you delete a pointer, and you
later plan to "check" if it's valid, it's up to you to SET it to null
immediately after deleting it. Otherwise, it is _impossible_ to
detect (and only your careful programming can ensure you don't use it.)
yes but I'm not the one deleting the pointer...TServerSocket is responsible
for deleting the TCustomWinSocket it generates when client connects...and
then should delete it after the client disconnects. For instance if I go to
windows task manager and end process on my client or my client hits the
power button on there computer or the client unplugs his internet
connection. It doesn't seem like I'm getting the OnClientDisconnect...at
least not right away...not sure I always get one or not.
so I have some TCustomSocket* s
try
{
byte someBuffer[10];
s->SendBuffer(someBuffer, 10);
}
catch(Exception& e)
{
ShowMessage(e.Message); // I get the eAccess violoation error;
//I think sometimes I get other errors as well but I'm just trying to
get the AccessVioloation error fixed for now
}
I'm not the one deleting s and am expecting a OnClientDisconnect to inform
me of this where I then set
s = NULL; I actually have a container class of TCustomWinSocket
I'm using a non blocking socket and all communication is done in this one
thread so I don't think its a thread issue.
A while back ago I was told that when using non blocking sockets the
exception can sometimes be thrown long after I use the SendBuffer. I forget
the exact reasoning behind this...not sure if this is related to this
discussion or not.
 

Re:Another Casting question

On Sat, 10 Jan 2004 00:22:09 -0600, JunkMail wrote:
Quote
This last line has a problem because ptrB was already deleted.
As it should. You shouldn't use deleted pointers.
--
Good luck!
liz
 

Re:Another Casting question

Hi!
JunkMail wrote:
Quote
I'm using a TServerSocket with type stNonBlocking. On a client connect I'm
saving the TCustomWinSocket* of the client for easy access.
The server is already doing that for you:
TCustomWinSocket* getConnection(TServerSocket *server, int index)
{
return server->Socket->Connections[index];
}
You can check the count first via server->Socket->ActiveConnections.
Frank
 

Re:Another Casting question

"JunkMail" < XXXX@XXXXX.COM >wrote in message
Quote
For instance if I go to windows task manager and end process
on my client or my client hits the power button on there computer
or the client unplugs his internet connection. It doesn't seem like
I'm getting the OnClientDisconnect...at least not right away...
You will always get the OnClientDisconnect event before the socket instance
is physically freed from memory. And when you do get the event, the Socket
instance is still valid in memory, it hasn't been freed yet. You may not
get the event immediately, but you will get it eventually. That is just the
nature of sockets in general - the socket stack may not see the disconnect
immediately unless it was explitically initiated programmably by the client
gracefully.
Quote
I'm not the one deleting s and am expecting a OnClientDisconnect
to inform me of this where I then set s = NULL; I actually have a
container class of TCustomWinSocket
If you are, in fact, getting AVs with your sockets, then you are not
managing your code correctly in the first place. In which case, please show
your actual code, your earlier descriptions are not enough to diagonose your
problem effectively.
Gambit
 

Re:Another Casting question

"JunkMail" < XXXX@XXXXX.COM >writes:
Quote
Boy I really screwed up that example...the text below the example doesn't
pertain to the example so I'll just repost the example.

class B
{
B();
virtual ~B();
};

class D : public B
{
D();
virtual ~D();
};

B* ptrB = new B();
delete ptrB;

D* ptrD = dynamic_cast<D*>(ptrB);
This last line has a problem because ptrB was already deleted.
Don't delete pointers until you're done using them. After you've
deleted the pointer, it's invalid to use its value in any way. If
your pointer is going to outlive the object that it points to, and you
might reuse it, then you need to set it to null after deleting it, or
else it's impossible to determine if the address it holds is valid.
I don't like designs that reuse pointers like that, if it can be
helped. I prefer pointers to "die" (by going out of scope) at the
same time the object they point to is deleted, so that there is no
possibility of ever accidently using the deleted value.
--
Chris (TeamB);