[omniORB] Help with allocating and deallocating - Try again
Duncan Grisby
dgrisby@uk.research.att.com
Tue, 12 Oct 1999 10:43:03 +0100
On Monday 11 October, David Hyde wrote:
> // The Session object. This is declared globally in the cpp file
> CBSession_ptr g_pSession;
>
>
> // Later on we see if we have a connection to g_pSession
> if (CORBA::is_nil(g_pSession))
> {
This is the first (minor) error, although it has nothing to do with
your problem. The CBSession_ptr is initialised to zero, but the CORBA
C++ mapping does not require that nil object references are mapped to
zero pointers. Indeed omniORB maps nil to a pointer to a singleton nil
object. So, calling is_nil() on a zero pointer is strictly-speaking
incorrect. However, omniORB is generous and lets you get away with
it. If you run with an ORB trace level greater than 10, you'll get a
warning.
> g_pSession =
> CBSession::_duplicate(pSessFactory->create());
The duplicate() here is wrong. The ownership rules for object
references says than ownership of a returned object reference is
passed to the caller. You should just say
g_pSession = pSessFactory->create();
On the server side, your factory should make sure it returns a
correctly reference counted object reference with a call to _this(),
like:
CBSession_i* si = new CBSession_i(...); // Create servant
return si->_this(); // Return object reference
> // Later still we've finished with g_pSession, so I get rid of it.
> // I don't use delete and I don't set it to to NULL because the
> documentation says not to do
> // this with CORBA pointers
> CORBA::release(g_pSession);
>
> // Now we want to use g_pSession again, but we have to have a new one made
> for us because we've got rid of the
> // old one. We do this again.
> if (CORBA::is_nil(g_pSession))
> {
> ...
>
>
> I would have thought that is_nil should return TRUE, but it returns FALSE.
This is because you haven't set the pointer to nil! The code you've
written is basically equivalent to the simple C++:
int* p = 0;
p = new int;
delete p;
if (p==0) {
...
The call to CORBA::release() just indicates that you are no longer
using the object reference. It does nothing to the pointer. You should
say:
CORBA::release(g_pSession);
g_pSession = CBSession::_nil();
if (CORBA::is_nil(g_pSession) {
....
and you'll find that is_nil() returns true.
> When I try to use the g_pSession object that I now think is valid the
> program crashes. I've wondered if I am doing something to screw up the
> reference counting, so I tried CORBA::release on g_pSession twice in the
> above code. Stepping into the OmniOrb code, during the first release(), I
> see that g_pSession's reference count is two. If I do the double release,
> though, the CORBA::is_nil call throws an exception. What I can say is that
> the first call to release is definitely causing the Session object's
> destructor to be called.
I'm not quite sure what is going on here. Given your earlier
superfluous duplicate(), I would expect the object reference to remain
valid after the first release(), and to be deleted after the second.
Cheers,
Duncan.
--
-- Duncan Grisby \ Research Engineer --
-- AT&T Laboratories Cambridge --
-- http://www.uk.research.att.com/~dpg1 --