When RTI Code Generator generates code for data structures with variable-length types—strings and sequences—it includes functions that create, initialize and finalize (destroy) those objects. These support functions will properly initialize pointers and allocate and deallocate the memory used for variable-length types. All Connext DDS APIs assume that the data structures passed to them are properly initialized.
For variable-length types, the actual length (instead of the maximum length) of data is transmitted on the wire when the DDS sample is written (regardless of whether the type has hard-coded bounds).
C, Traditional C++, C++/CLI, and C# users can allocate memory from a number of sources: from the heap, the stack, or from a custom allocator of some kind. In those languages, sequences provide the concept of memory "ownership." A sequence may own the memory allocated to it or be loaned memory from another source. If a sequence owns its memory, it will manage its underlying memory storage buffer itself. When a sequence's maximum size is changed, the sequence will free and reallocate its buffer as needed. However, if a sequence was created with loaned memory by user code, then its memory is not its own to free or reallocate. Therefore, you cannot set the maximum size of a sequence whose memory is loaned. See the API Reference HTML documentation, which is available for all supported programming languages (select Modules, RTI Connext DDS API Reference, Infrastructure Module, Sequence Support) for more information about how to loan and unloan memory for sequence.
In IDL, as described above, a sequence may be declared as bounded or unbounded. A sequence's "bound" is the greatest value its maximum may take. If you use the initializer functions RTI Code Generator provides for your types, all sequences will have their maximums set to their declared bounds. However, the amount of data transmitted on the wire when the DDS sample is written will vary.
In the Modern C++ API, sequences (dds::core::vector) always own the memory.
(Note: this section doesn't apply to the Modern C++ API, where dds::core::string behaves similarly to std::string)
The initialization functions that RTI Code Generator provides for your types will allocate all of the memory for strings in a type to their declared bounds. Take care—if you assign a string pointer (char *) in a data structure allocated or initialized by a Connext DDS-generated function, you should release (free) the memory originally allocated for the string, otherwise the memory will be leaked.
To Java and .NET users, an IDL string is a String object: it is immutable and knows its own length. C and C++ users must take care, however, as there is no way to determine how much memory is allocated to a character pointer "string"; all that can be determined is the string's current logical length. In some cases, Connext DDS may need to copy a string into a structure that user code has provided. Connext DDS does not free the memory of the string provided to it, as it cannot know from where that memory was allocated.
In the C and C++ APIs, Connext DDS therefore uses the following conventions:
Connext DDS provides a small set of C functions for dealing with strings. These functions simplify common tasks, avoid some platform-specific issues (such as the lack of a strdup() function on some platforms), and provide facilities for dealing with wide strings, for which no standard C library exists. Connext DDS always uses these functions internally for managing string memory; you are recommended—but not required—to use them as well. See the API Reference HTML documentation, which is available for all supported programming languages (select Modules, RTI DDS API Reference, Infrastructure Module, String Support) for more information about strings.
© 2016 RTI