Considerations When Using C++ Standard Library

When -cpp11 is specified on the command line, the generated code may use features of the C++ Standard Library such as std::string for character strings and std::list (or another container class) for SEQUENCE OF types. There are a few considerations to keep in mind when using this option.

ASN1C generates code that manages memory using OSCTXT and rtxMem* functions. The design of the generated code and memory management is such that the C++ constructors and destructors generally don't need to be invoked. For example, dynamic memory is allocated using rtxMemAllocType, instead of new, and initialization can be done by assigning individual fields or else using a generated asn1Init* function, so that the constructor is never invoked.

The C++ Standard Library classes are more typical C++ classes, and failing to invoke their constructor or destructor, or invoking them more than once, can lead to memory leaks or crashes. This means that when you are using the -cpp11 option, you must take care that the C++ constructors and destructors for the generated classes are invoked exactly once. Follow these rules to avoid problems:

A few code examples are given below.

EXAMPLE 1, Using a local variable:

   //A local variable's constructor & destructor fire automatically.  You only need to
   //make sure asn1Free* is invoked.  Using a control class, as show here, does that for you.
   ASN1T_PDU msgData;
   ASN1C_PDU controlPDU (encodeBuffer, msgData);

   // Populate structure of generated type
   ...

   // Encode
   ...

   // When controlPDU goes out of scope, asn1Free_PDU will be invoked on msgData
   // When msgDta goes out of scope, its destructor will fire

EXAMPLE 2, Assigning a dynamically allocated std::string for a choice type:

   OSCTXT* pctxt;
   ...

   //set the selector indicating which alternative is chosen
   pvalue->myChoice.t = 1;

   //allocate memory for the chosen alternative
   pvalue->myChoice.u.message = rtxMemAllocTypeZ (pctxt, std::string);

   //invoke the constructor using placement new expression
   new (pvalue->myChoice.u.message) std::string();

   //Assign the contents of the string.
   *pvalue->myChoice.u.message = "Happy Birthday!";

EXAMPLE 3, Dynamically allocating and freeing an object:

   OSCTXT* pctxt;
   ...

   //dynamically allocate and construct the object
   ASN1T_StringsInSequence* pvalue = rtxMemAllocType (pctxt, ASN1T_StringsInSequence);

   if (pvalue == NULL)
      return LOG_RTERR (pctxt, RTERR_NOMEM);

   new (pvalue) ASN1T_StringsInSequence();

   //do some work, maybe decode into pvalue
   ...

   //invoke asn1Free*, destruct, and free memory
   asn1Free_StringsInSequence (pctxt, pvalue);
   pvalue->~ASN1T_StringsInSequence();
   rtxMemFreePtr (pctxt, (void*)pvalue);