Problem:
- Product Name: VisiBroker C
- Product Version: All
- Product Component: CORBA Any
- Platform: All
The 2 operations on Any types are ‘<<=’ for insertion and ‘>>=’ for extraction. Insertion of data into CORBA::Any can be categorized into primitive or complex data type.
1. Insertion of basic/primitive types will not cause memory corruption.
// C
void operator<<=(CORBA::Any&, T);
It is sufficient for most basic data types T (passed by value) (ie. short, long, float).
2. Insertion of compound/complex data types.
// C
void operator<<=(CORBA::Any&, const T&); // copying insertion
void operator<<=(CORBA::Any&, T*); // consuming insertion
// IDL – Bank module
struct Account{
long id;
string owner;
long balance;
}
How can I prevent a memory leak or corruption with CORBA::Any datatype?
Resolution:
A. Copying insertion
A copying insertion will create a ‘deep’ copy of the data and puts the copied data under the ownership of the Any.
{
CORBA::Any theAny; // empty
Bank::Account accountA;
accountA.id = (CORBA::Long)1;
accountA.owner = CORBA::string_dup("A");
accountA.balance = (CORBA::Long)1000;
// ‘theAny’ makes a deep copy of ‘accountA’ and assumes its ownership
theAny <<= accountA;
Bank::Account_var accountB = new Bank::Account();
accountB->id = (CORBA::Long)2;
accountB->owner = CORBA::string_dup("B");
accountB->balance = (CORBA::Long)1000;
// 1. Current data referred by ‘theAny’ deleted.
// 2. A deep copy of ‘*accountB’ created and
// ‘theAny’ assumes its ownership.
theAny <<= *accountB;
CORBA::release(theAny);
}
De-allocation of original data remains the responsibility of smart pointer ‘accountB’, while the de-allocation of new copy will be with ‘theAny’. Please use CORBA::release() to delete the CORBA object references.
B. Consuming insertion
A consuming insertion puts the original data under the ownership of the Any instead of making a copy of data like ‘copying insertion’.
{
CORBA::Any theAny;
Bank::Account* accountA = new Bank::Account();
accountA->id = (CORBA::Long)1;
accountA->owner = CORBA::string_dup("A");
accountA->balance = (CORBA::Long)1000;
// ‘theAny’ makes a shallow copy of the Bank::Account and assumes
// ownership of the data
theAny <<= accountA;
Bank::Account_var accountB = new Bank::Account();
accountB->id = (CORBA::Long)2;
accountB->owner = CORBA::string_dup("B");
accountB->balance = (CORBA::Long)1000;
// 1. the ‘accountB’ give up the ownership by invoking _retn()
// 2. Current data referred by ‘theAny’ deleted
// 3. ‘theAny’ assumes the ownership of the original data.
theAny <<= accountB._retn();
CORBA::release(theAny);
}
However a tricky part is with a smart pointer (_var). Different from copying insertion, a smart point (_var) need to give up the ownership to the original data (by calling _retn()) before making the insertion to CORBA::Any.
*** NEVER insert a ‘_var’ directly to CORBA::Any, as it will result in both _var and CORBA::Any owning the data. Subsequently, memory corruption may occur when both try to delete the same block of memory (double deletion).
#VisiBroker
#C
#memorymanagement
#c
#CORBAAny
#IDL
#Security