Dynamic Memory Management
The ASN1C run-time uses specialized dynamic memory functions to improve the performance of the encoder/decoder. It is imperative that the user understands how this methodology works in order to avoid memory problems in their applications.
The algorithm used is called the nibble-allocation algorithm. What this means is that large blocks of memory are allocated up front and then split up to provide memory for smaller allocation requests. This reduces the number of calls required to the C malloc and free functions. These functions are very expensive in terms of performance.
The large blocks of memory are tracked through the ASN.1 context block (ASN1CTXT) structure. For C, this means that an initialized context block is required for all memory allocations and deallocations. All allocations are done using this block as an argument to routines such as rtMemAlloc. All memory can be released at once when a user is done with a structure containing dynamic memory items by calling rtMemFree. Other functions are available for doing other dynamic memory operations as well. See the C/C++ Run-time Reference Manual for details on these.
In the case of C++, the ownership of memory is handled by the control class and message buffer objects. These classes share a context structure and use reference counting to manage the allocation and release of the context block. When a message buffer object is created, a context block structure is created as well. When this object is then passed into a control class constructor, its reference count is incremented. Then when either the control class object or message buffer object are deleted or go out of scope, the count is decremented. When the count goes to zero (i.e. when both the message buffer object and control class object go away) the context structure is released.
What this means to the user is that they must keep a control class or message buffer object in scope when using a data structure associated with that class. A common mistake is to try and pass a data variable out of a method and using it after the control and message buffer objects go out of scope. For example, consider the following code fragment:
ASN1T_<type>* func2 () { ASN1T_<type>* p = new ASN1T_<type> (); ASN1BERDecodeBuffer decbuf; ASN1C_<type> cc (decbuf, *p); cc.Decode(); // After return, cc and decbuf go out of scope; therefore // all memory allocated within struct p is released.. return p; }void func1 () { ASN1T_<type>* pType = func2 (); // pType is not usable at this point because dynamic memory // has been released.. }
Objective Systems, Inc.102 Pickering Way, Suite #506Exton, Pennsylvania 19341 http://www.obj-sys.com Phone: (484) 875-9841 Toll-free: (877) 307-6855 (US only) Fax: (484) 875-9830 info@obj-sys.com |