Dynamic Memory Management

In the case of C++, dynamic memory management is handled by the new and delete operators. In most cases, handling memory involves the common action of making sure to delete any pointer that was allocated with new when done with it. The C++ memory management policy for XBinder v1.2 and above is to deep-copy all non-atomic variables on assignment. This differs from earlier versions where an ownMemory flag was used to assign ownership. Now, all XBinder classes hold their own copy of objects which are automatically deleted on desctruction.

One exception to this rule is for a control class. A flag and a utility method in the control class are used to assign ownership. When an XML instance is decoded, if a reference to a variable to receive the decoded data has not been provided, memory will be allocated internally within the class to hold the data. This memory will be freed when the control class object is deleted or goes out of scope. The exception to this rule is if the user uses the non-const version of the getValue method to get a pointer to the value. In this case, ownership of the memory is transferred to the user who is then responsible for freeing it using the delete operator.

An example of a control class is shown below (this is taken from the cpp/sample/Employee sample program):

class EXTERN personnelRecord_CC : public OSXSDGlobalElement {
   protected:
      ::PersonnelRecord * mpValue;
      OSBOOL mbOwnMemory;
      ...
   public:
      ...
      inline ::PersonnelRecord* getValue()
         { setOwnMemory (FALSE); return mpValue; }
      inline const ::PersonnelRecord* getValue() const { return mpValue; }
      ...
      /**
      * This method transfers ownership of the string memory to the
      * class instance.  The memory will be deleted when the instance
      * is deleted or goes out of scope.
      *
      * @param bvalue     - Boolean value.
      */
      inline void setOwnMemory (OSBOOL bvalue=TRUE) { mbOwnMemory=bvalue; }
...
} ;
            
int personnelRecord_CC::decodeFrom (OSRTMessageBufferIF& msgbuf)
{
   ...
   if (0 == mpValue) {
      mpValue = new ::PersonnelRecord;
            
      if (mpValue == NULL)
         return LOG_RTERR (pctxt, RTERR_NOMEM);
            
      setOwnMemory();
   }
   ...
}

An code segment from a reader program that calls non-const version of thegetValue method is shown below:

if (0 == stat) {
   pValue = pdu.getValue();
...
}
...
delete pValue;

The other exception to this rule is the linked-list class append method. In cases where an object list is used, it is assumed that the user has allocated the object using new and is turning over management of the memory to the list class. This means that when the list is destroyed, all objects inside are destroyed as well. A second method called appendCopy is available in generated linked-list based classes that allows a copy of the given object to be made and assigned to the list.

An example of a class with a built-in list and the methods that are generated is shown below (this is taken from the cpp/sample/simpleArray sample program):

 
class SimpleArray : public OSRTBaseType {
  public:
      // List of OSXMLStringClass
      class item_list : public OSRTObjListClass {
        public:
           void append (OSXMLStringClass* pdata) {
           OSRTDListClass::append ((const void*)pdata);
        }
        void appendCopy (const OSXMLStringClass* pdata) {
           OSRTDListClass::appendCopy ((void*)pdata);
        }
        const OSXMLStringClass* getItem (int idx) {
           return (const OSXMLStringClass*)
           OSRTDListClass::getItem (idx);
        }
  } item;
  ...

In this case, the item list is a list of strings. The append method directly assigned the given pointer variable to the list. The appendCopy method first makes a copy of the item and then assigned it to the list. When the list is deleted, all of the objects in the list are deleted as well.

When an XML instance is decoded, the decoder automatically transfers memory ownership to the container objects. It is therefore not necessary for the user to worry about freeing memory for any of the items within a returned class instance. Deleting the main object is all that is necessary to free the memory of all of the items within.