[omniORB] Sequences/allocbuf/freebuf comment
Yan Pujante
yan@corp.socialnet.com
Thu, 15 Feb 2001 09:22:37 -0800
Hello
I am not sure it is the right place for this kind of comment but here it is. I
am using a sequence of structures (in IDL: typedef sequence<C> CSeq;)
I really like in the CORBA spec how you get a C_var defined for you and you use
it this way:
C *myfunc()
{
C_var c = new C();
// do stuff (which can potentially throws an exception)
return c._retn(); // remove the ownership
}
But there is no equivalent for an array of C used in a sequence. According to
the spec, you are supposed to create it using CSeq::allocbuf and free it using
CSeq::freebuf. So the code would be:
C *array = CSeq::allocbuf(n);
// initialize each element of the array...
// this can potentially throws an exception
// here I am giving the ownership of the array to the sequence
// so I don't have to free it myself
CSeq_var seq = new CSeq(n, n, array, true);
return seq._retn();
The problem in this code is that it can potentially leak memory if something
wrong happen between allocbuf and the transfer of ownership.
Hence the idea of creating a wrapper equivalent to the _var contruct:
template <class T, class U>
class TUBuf
{
public:
inline TUBuf(int nElems) : _buf(U::allocbuf(nElems)) {}
inline TUBuf(T *buf) : _buf(buf) {}
inline T& operator[] (int idx) { return _buf[idx]; }
inline T *_retn() { T *tmp = _buf; _buf = NULL; return tmp; }
inline ~TUBuf() { if(_buf) U::freebuf(_buf); }
private:
T *_buf;
};
Then the previous code can be rewritten:
TUBuf< C, CSeq > array(n);
// initialize each element of the array...
// this can potentially throws an exception
// here I am giving the ownership of the array to the sequence
CSeq_var seq = new CSeq(n, n, array._retn(), true);
return seq._retn();
Now it is safe. My only concern is that I have to write a function taking 2
template parameters because in the code generated there is no way of extracting
C from CSeq
A code like that would do the job:
class CSeq : ....
{
typedef C _myType; // traditionnal construct found everywhere in STL
....
}
Then the template function could be rewritten:
template <class U>
class TUBuf
{
public:
typedef typename U::_myType T;
inline TUBuf(int nElems) : _buf(U::allocbuf(nElems)) {}
inline TUBuf(T *buf) : _buf(buf) {}
inline T& operator[] (int idx) { return _buf[idx]; }
inline T *_retn() { T *tmp = _buf; _buf = NULL; return tmp; }
inline ~TUBuf() { if(_buf) U::freebuf(_buf); }
private:
T *_buf;
};
and finally the allocation code:
TUBuf< CSeq > array(n);
Yan
--
http://eowyn.fr.eu.org/~yan/ | yan@corp.socialnet.com