A string in OMG IDL is mapped to char * in C++. Both bounded and unbounded strings are mapped to
char *. CORBA strings in C++ are NULL-terminated and can be used wherever a char *
type is used.
Note:
|
The string_alloc function allocates len+1 characters so that the resulting string has enough space to hold a trailing NULL character.
|
OMG IDL defines a wchar data type that encodes wide characters from any character set. As with character data, an implementation is free to use any code set internally for encoding wide characters, though, again, conversion to another form may be required for transmission. The size of
wchar is implementation-dependent.
Note:
|
The wchar and wstring data types enable users to interact with computers in their native written language. Some languages, such as Japanese and Chinese, have thousands of unique characters. These character sets do not fit within a byte. A number of schemes have been used to support multi-byte character sets, but they have proved to be unwieldy to use. Wide characters and wide strings make it easier to interact with this kind of complexity.
|
The wstring data type represents a sequence of
wchar, except the wide character NULL. The type
wstring is similar to that of type string, except that its element type is
wchar instead of
char. The actual length of a
wstring is set at run time and, if the bounded form is used, must be less than or equal to the bound.
wstring types are built in types just like unsigned long, char, string, double, etc. They can be used directly as parameters, typedef'd, used to construct structs, sequences, unions, arrays, and so forth.
Note:
|
The wchar and wstring data types enable users to interact with computers in their native written language. Some languages, such as Japanese and Chinese, have thousands of unique characters. These character sets do not fit within a byte. A number of schemes have been used to support multi-byte character sets, but they have proved to be unwieldy to use. Wide characters and wide strings make it easier to interact with this kind of complexity.
|
Depending upon the data type of the union member, additional modifier functions are generated. The member functions generated for each data
type are as follows:
•
|
Object and pseudo-object
For object and Typecode types with member name objtype, member functions are generated as follows: void objtype (TYPE); // modifier TYPE objtype () const; // accessor
For the mapping from an OMG IDL data type to the C++ data type TYPE, see Table 13‑1. The modifier member function does not assume ownership of the specified object reference argument. Instead, the modifier duplicates the object reference or pseudo-object reference. You are responsible for releasing the reference when it is no longer required.
|
•
|
Enum
For an enum TYPE with member name enumtype, member functions are generated as follows: void enumtype (TYPE); // modifier TYPE enumtype () const; // accessor
|
•
|
String
For strings, one accessor and three modifier functions are generated, as follows:
void stringInfo (char *); // modifier 1 void stringInfo (const char *); // modifier 2 void stringInfo (const CORBA::String_var &); // modifier 3 const char * stringInfo () const; // accessor
The first modifier assumes ownership of the char * parameter passed to it and the union is responsible for calling the CORBA::string_free member function on this string when the union value changes or when the union is destroyed. The second and third modifiers make a copy of the specified string passed in the parameter or contained in the string var. The accessor function returns a pointer to internal memory of the union; do not attempt to free this memory, and do not access this memory after the union value has been changed or the union has been destroyed.
|
TYPE( const TYPE & From);
TYPE &operator=(const TYPE & From);
When the _d() modifier is invoked on a new instance of a union, Tuxedo C++ relaxes the "implicit switching" restriction. In this case, no exception is thrown, and the union is not affected.
•
|
Operator[] functions to access or modify sequence elements
|
You must set the length before accessing any elements.
The operator[] functions are used to access or modify the sequence element. These operators return a reference to the sequence element. The OMG IDL sequence base type is mapped to the appropriate C++ data type.
For basic data types, see Table 13‑1. For object references, TypeCode references, and strings, the base type is mapped to a generated
_ForSeq_var class. The
_ForSeq_var class provides the capability to update a string or an object that is stored within the sequence. This generated class has the same member functions and signatures as the corresponding var class. However, this
_ForSeq_var class honors the setting of the release parameter in the sequence constructor. The distinction is that the
_ForSeq_var class lets users specify the
Release flag, thereby allowing users to control the freeing of memory.
Determines whether elements are released. If this flag has a value of CORBA_TRUE, the sequence assumes ownership of the buffer pointed to by the
Value argument. If the
Release flag is
CORBA_ TRUE, this buffer must be allocated using the
allocbuf member function, because it will be freed using the
freebuf member function when the sequence is destroyed.
This function sets the current length of the sequence. The Length argument specifies the new length of the sequence. If the sequence is unbounded and the new length is greater than the current maximum, the buffer is reallocated and the elements are copied to the new buffer. If the new length is greater than the maximum, the maximum is set to the new length.
TYPE & operator[](CORBA::ULong Index);
const TYPE & operator[](CORBA::ULong Index) const;
static TYPE * allocbuf(CORBA::ULong NumElems);
This static function frees a TYPE * sequence buffer allocated by the
allocbuf function. The
Value argument specifies the
TYPE * buffer allocated by the
allocbuf function. A 0 (zero) pointer is ignored.
static TYPE_slice * TYPE_alloc(void);
This function allocates a TYPE array, returning a pointer to the allocated
TYPE array. If the array cannot be dynamically allocated, 0 (zero) is returned.
•
|
A static _narrow function, to determine the type of exception
|
static TYPE * _narrow(CORBA::Exception_ptr Except);
This function returns a pointer to a TYPE exception class if the exception can be narrowed to a
TYPE exception. If the exception cannot be narrowed, 0 (zero) is returned. The
TYPE pointer is not a pointer to a new class. Instead, it is a typed pointer to the original exception pointer and is valid only as long as the Except parameter is valid.
TYPE (const TYPE & From);
TYPE & operator=(const TYPE & From);
•
|
Their declarations may refer to other 1 serverless object types that are not otherwise necessarily allowed in OMG IDL.
|
The pseudo prefix means that the interface may be implemented in either a normal or serverless fashion. That is, apply either the rules described in the following sections, or the normal mapping rules described in this chapter.
•
|
Legal implementations of _duplicate include simply returning the argument or constructing references to a new instance. Individual implementations may provide stronger guarantees about behavior.
|
•
|
In C++ PIDL, release performs the role of the associated free and delete operations in the C mapping, unless otherwise noted.
|
If conversion of an ObjectId to a string would result in illegal characters in the string (such as a NULL), the first two functions throw the
CORBA::BAD_PARAM exception.
For an interface INTF, the generated interface code contains the following items:
•
|
_nil static member function
|
static INTF_ptr _duplicate (INTF_ptr Obj)
This static member function duplicates an existing INTF object reference and returns a new
INTF object reference. The new
INTF object reference must be released by calling the
CORBA::release member function. If an error occurs, a reference to the nil
INTF object is returned. The argument
Obj specifies the object reference to be duplicated.
static INTF_ptr _narrow (CORBA::Object_ptr Obj)
This static member function returns a new INTF object reference given an existing
CORBA::Object_ptr object reference. The
Object_ptr object reference may have been created by a call to the
CORBA::ORB::string_to_object member function or may have been returned as a parameter from an operation.
The INTF_ptr object reference must correspond to an
INTF object or to an object that inherits from the
INTF object. The new
INTF object reference must be released by calling the
CORBA::release member function. The argument
Obj specifies the object reference to be narrowed to an
INTF object reference. The
Obj parameter is not modified by this member function and should be released by the user when it is no longer required. If
Obj cannot be narrowed to an
INTF object reference, the
INTF nil object reference is returned.
The INTF_var class simplifies memory management by automatically releasing the object reference when the
INTF_var class goes out of scope or is reassigned. Variable types are generated for many of the UDTs and are described in
Using var Classes.
An any in OMG IDL is mapped to the
CORBA::Any class. The
CORBA::Any class handles C++ types in a type-safe manner.
To decrease the chances of creating an any with a mismatched TypeCode and value, the C++ function overloading facility is utilized. Specifically, for each distinct type in an OMG IDL specification, overloaded functions to insert and extract values of that type are provided. Overloaded operators are used for these functions to completely avoid any name space pollution. The nature of these functions, which are described in detail below, is that the appropriate TypeCode is implied by the C++ type of the value being inserted into or extracted from the
any.
Since the type-safe any interface described below is based upon C++ function overloading, it requires C++ types generated from OMG IDL specifications to be distinct. However, there are special cases in which this requirement is not met:
•
|
Short, UShort, Long, ULong, Float, Double
|
•
|
For the copying version of operator<<=, the lifetime of the value in the Any is independent of the lifetime of the value passed to operator<<=. The implementation of the Any does not store its value as a reference or a pointer to the value passed to operator<<=.
|
•
|
For the noncopying version of operator<<=, the inserted T* is consumed by the Any. The caller may not use the T* to access the pointed-to data after insertion because the Any assumes ownership of T*, and the Any may immediately copy the pointed-to data and destroy the original.
|
•
|
With both the copying and noncopying versions of operator<<=, any previous value held by the Any is properly deallocated. For example, if the Any(TypeCode_ptr,void*,TRUE) constructor (described in Handling Untyped Values) were called to create the Any, the Any is responsible for deallocating the memory pointed to by the void* before copying the new value.
|
The Array_forany types are always passed to
operator<<= by reference to
const.
The
nocopy flag in the
Array_forany constructor is used to control whether the inserted value is copied (
nocopy == FALSE) or consumed (
nocopy == TRUE). Because the
nocopy flag defaults to
FALSE, copying insertion is the default.
Line 1 results in the invocation of the noncopying operator<<=(Any&, S*) due to the decay of the
SA array type into a pointer to its first element, rather than the invocation of the copying
SA_forany insertion operator. Line 2 explicitly constructs the
SA_forany type and thus results in the desired insertion operator being invoked.
In this case, the version of operator>>= for type
Long determines whether the Any truly does contain a value of type
Long and, if so, copies its value into the reference variable provided by the caller and returns
TRUE. If the Any does not contain a value of type
Long, the value of the caller’s reference variable is not changed, and
operator>>= returns
FALSE.
If the extraction is successful, the caller’s pointer points to storage managed by the Any, and operator>>= returns
TRUE. The caller must not try to
delete or otherwise release this storage. The caller also should not use the storage after the contents of the Any variable are replaced via assignment, insertion, or the
replace function, or after the Any variable is destroyed. Care must be taken to avoid using
T_var types with these extraction operators, since they will try to assume responsibility for deleting the storage owned by the Any.
The Array_forany types are always passed to
operator>>= by reference.
The operator>>= is also supported on the
Any_var type.
The to_object helper type is used to extract an object reference from an Any as the base Object type. If the Any contains a value of an object reference type as indicated by its TypeCode, the extraction function
operator>>=(to_object) explicitly widens its contained object reference to Object and returns
TRUE; otherwise, it returns FALSE. This is the only object reference extraction function that performs widening on the extracted object reference. As with regular object reference extraction, no duplication of the object reference is performed by the
to_object extraction operator.
The constructor duplicates the given TypeCode pseudo-object reference. If the release parameter is
TRUE, the Any object assumes ownership of the storage pointed to by the
value parameter. A caller should make no assumptions about the continued lifetime of the
value parameter once it has been handed to an Any with
release=TRUE, since the Any may copy the
value parameter and immediately free the original pointer. If the
release parameter is
FALSE (the default case), the Any object assumes that the caller manages the memory pointed to by
value. The
value parameter can be a NULL pointer.
The replace function is intended to be used with types that cannot be used with the type-safe insertion interface, and so is similar to the constructor described above. The existing TypeCode is released and value storage is deallocated, if necessary. The TypeCode
function parameter is duplicated. If the
release parameter is
TRUE, the Any object assumes ownership for the storage pointed to by the
value parameter. The Any should make no assumptions about the continued lifetime of the
value parameter once it has been handed to the
Any::replace function with
release=TRUE, since the Any may copy the
value parameter and immediately free the original pointer. If the
release parameter is
FALSE (the default case), the Any object assumes that the caller manages the memory occupied by the value. The
value parameter of the
replace function can be a NULL pointer.
Note that neither the constructor shown above nor the replace function is type-safe. In particular, no guarantees are made by the compiler at run time as to the consistency between the TypeCode and the actual type of the
void* argument. The behavior of an ORB implementation when presented with an
Any that is constructed with a mismatched TypeCode and value is not defined.
The type function returns a
TypeCode_ptr pseudo-object reference to the TypeCode associated with the Any. Like all object reference return values, the caller must release the reference when it is no longer needed, or assign it to a
TypeCode_var variable for automatic management.
The value function returns a pointer to the data stored in the Any. If the Any has no associated value, the
value function returns a NULL pointer.
The default constructor creates an Any with a TypeCode of type tk_null, and no value. The copy constructor calls
_duplicate on the
TypeCode_ptr of its Any parameter and deep-copies the parameter’s value. The assignment operator releases its own
TypeCode_ptr and deallocates storage for the current value if necessary, then duplicates the
TypeCode_ptr of its Any parameter and deep-copies the parameter’s value. The destructor calls
release on the
TypeCode_ptr and deallocates storage for the value, if necessary.
This is the default constructor for the TYPE_var class. The constructor initializes to 0 (zero) the
TYPE * owned by the var class. You may not invoke the
operator-> on a
TYPE_var class unless a valid
TYPE * has been assigned to it.
This copy constructor allocates a new TYPE and makes a deep copy of the data contained in the
TYPE owned by the
From parameter. When the
TYPE_var is destroyed, the copy of the
TYPE is released or deleted. The
From parameter specifies the var class that points to the
TYPE to be copied.
This assignment operator assumes ownership of the TYPE pointed to by the
NewValue parameter. If the
TYPE_var currently owns a
TYPE, it is released before assuming ownership of the
NewValue parameter. The
NewValue argument is a pointer to the
TYPE to be owned by this var class. This pointer must not be 0 (zero).
This assignment operator allocates a new TYPE and makes a deep copy of the data contained in the
TYPE owned by the
From TYPE_var parameter. If
TYPE_var currently owns a
TYPE, it is released. When the
TYPE_var is destroyed, the copy of the
TYPE is released. The
From parameter specifies the var class that points to the data to be copied.
These operators return a pointer to the TYPE owned by the var class. The var class continues to own the
TYPE and it is the responsibility of the var class to release
TYPE. You cannot use the
operator-> until the var owns a valid
TYPE. Do not try to release this return value or access this return value after the
TYPE_var has been destroyed.
Because implicit conversions can sometimes cause a problem with some C++ compilers and with code readability, the TYPE_var types also support member functions that allow them to be explicitly converted for purposes of parameter passing. To pass a
TYPE_var and an
in parameter, call the
in() member function; for
inout parameters, the
inout() member function; for
out parameters, the
out() member function. To obtain a return value from the
TYPE_var, call the
_return() function. For each
TYPE_var type, the return types of each of these functions will match the type shown in
Table 13‑7 for the
in,
inout,
out, and return modes for the underlying type
TYPE, respectively.
|
|
|
TYPE * operator-> () TYPE * operator-> () const
|
|
TYPE * operator-> () TYPE * operator-> () const
|
|
TYPE * operator-> () TYPE * operator-> () const TYPE & operator[](CORBA::Long index)
|
|
TYPE_slice & operator[](CORBA::Long index) TYPE_slice & operator[](CORBA::Long index) const
|
This operator invokes the operator[] of sequence owned by the var class. The
operator[] returns a reference to the appropriate element of the sequence at the specified index. The
Index argument specifies the index of the element to return. This index cannot be greater than the current sequence length.
Array vars do not support operator->, but do support the following additional
operator[] member functions to access the array elements:
This constructor makes a String_var from a string. The
str argument specifies the string that will be assumed. The user must not use the
str pointer to access data.
This constructor makes a String_var from a const
string. The
str argument specifies the const string that will be copied. The
var argument specifies a reference to the string to be copied.
|
|
|
TYPE * operator-> () TYPE * operator-> () const
|
|
TYPE * operator-> () TYPE * operator-> () const
|
|
TYPE * operator-> () TYPE * operator-> () const TYPE & operator[](CORBA::Long index)
|
|
TYPE_slice & operator[](CORBA::Long index) TYPE_slice & operator[](CORBA::Long index) const
|
When a TYPE_var is passed as an
out parameter, any previous value it referred to must be implicitly deleted. To give the ORB enough hooks to meet this requirement, each
T_var type has a corresponding
TYPE_out type that is used solely as the
out parameter type.
Note:
|
The _out classes are not intended to be instantiated directly by the programmer. Specify an _out class only in function signatures.
|
// assignment from TYPE_var not allowed
void operator=(const TYPE_var&):
};
The first constructor binds the reference data member with the T*& argument and sets the pointer to the zero (0) pointer value. The second constructor binds the reference data member with the pointer held by the
TYPE_var argument, and then calls
delete on the pointer (or
string_free() in the case of the
String_out type or
TYPE_free() in the case of a
TYPE_var for an array type
TYPE). The third constructor, the copy constructor, binds the reference data member to the same pointer referenced by the data member of the constructor argument.
Assignment from another TYPE_out copies the
TYPE* referenced by the
TYPE_out argument to the data member. The overloaded assignment operator for
TYPE* simply assigns the pointer argument to the data member. Note that assignment does not cause any previously held pointer to be deleted; in this regard, the
TYPE_out type behaves exactly as a
TYPE*. The
TYPE*& conversion operator returns the data member. The
ptr() member function, which can be used to avoid having to rely on implicit conversion, also returns the data member. The overloaded arrow operator (
operator->()) allows access to members of the data structure pointed to by the
TYPE* data member. Compliant applications may not call the overloaded
operator->() unless the
TYPE_out has been initialized with a valid nonNULL
TYPE*.
Assignment to a TYPE_out from instances of the corresponding
TYPE_var type is disallowed because there is no way to determine whether the application developer wants a copy to be performed, or whether the
TYPE_var should yield ownership of its managed pointer so it can be assigned to the
TYPE_out. To perform a copy of a
TYPE_var to a
TYPE_out, the application should use
new, as follows:
// C++
TYPE_var t = ...;
my_out = new TYPE(t.in()); // heap-allocate a copy
The in() function called on
t typically returns a
const TYPE&, suitable for invoking the copy constructor of the newly allocated
T instance.
Alternatively, to make the TYPE_var yield ownership of its managed pointer so it can be returned in a
T_out parameter, the application should use the
TYPE_var::_retn() function, as follows:
// C++
TYPE_var t = ...;
my_out = t._retn(); // t yields ownership, no copy
Note that the TYPE_out types are not intended to serve as general-purpose data types to be created and destroyed by applications; they are used only as types within operation signatures to allow necessary memory management side-effects to occur properly.
When a _var is passed as an
out parameter, any previous value it refers to must be implicitly released. To give C++ mapping implementations enough hooks to meet this requirement, each object reference type results in the generation of an
_out type that is used solely as the
out parameter type. For example, interface
TYPE results in the object reference type
TYPE_ptr, the helper type
TYPE_var, and the
out parameter type
TYPE_out. The general form for object reference
_out types is as follows:
// C++
class TYPE_out
{
public:
TYPE_out(TYPE_ptr& p) : ptr_(p) { ptr_ = TYPE::_nil(); }
TYPE_out(TYPE_var& p) : ptr_(p.ptr_) {
release(ptr_); ptr_ = TYPE::_nil();
}
TYPE_out(TYPE_out& a) : ptr_(a.ptr_) {}
TYPE_out& operator=(TYPE_out& a) {
ptr_ = a.ptr_; return *this;
}
TYPE_out& operator=(const TYPE_var& a) {
ptr_ = TYPE::_duplicate(TYPE_ptr(a)); return *this;
}
TYPE_out& operator=(TYPE_ptr p) { ptr_ = p; return *this; }
operator TYPE_ptr&() { return ptr_; }
TYPE_ptr& ptr() { return ptr_; }
TYPE_ptr operator->() { return ptr_; }
private:
TYPE_ptr& ptr_;
};
This operator invokes the operator[] of the sequence owned by the out class. The
operator[] returns a reference to the appropriate element of the sequence at the specified index. The
Index argument specifies the index of the element to return. This index cannot be greater than the current sequence length.
Array outs do not support operator->, but do support the following additional
operator[] member functions to access the array elements:
When a String_var is passed as an
out parameter, any previous value it refers to must be implicitly freed. To give C++ mapping implementations enough hooks to meet this requirement, the string type also results in the generation of a
String_out type in the CORBA namespace that is used solely as the string
out parameter type. The general form for the
String_out type is as follows:
The first constructor binds the reference data member with the char*& argument. The second constructor binds the reference data member with the
char* held by the
String_var argument, and then calls
string_free() on the string. The third constructor, the copy constructor, binds the reference data member to the same
char* bound to the data member of its argument.
Assignment from another String_out copies the
char* referenced by the argument
String_out to the
char* referenced by the data member. The overloaded assignment operator for
char* simply assigns the
char* argument to the data member. The overloaded assignment operator for
const char* duplicates the argument and assigns the result to the data member. Note that the assignment does not cause any previously held string to be freed; in this regard, the
String_out type behaves exactly as a
char*. The
char*& conversion operator returns the data member. The
ptr() member function, which can be used to avoid having to rely on implicit conversion, also returns the data member.
Assignment from String_var to a
String_out is disallowed because of the memory management ambiguities involved. Specifically, it is not possible to determine whether the string owned by the
String_var should be taken over by the
String_out without copying, or if it should be copied. Disallowing assignment from
String_var forces the application developer to make the choice explicitly, as follows:
The mapping for out and
inout parameters additionally requires support for deallocating any previous variable-length data in the parameter when a
T_var is passed. Even though their initial values are not sent to the operation, the Oracle Tuxedo includes
out parameters because the parameter could contain the result from a previous call. The provision of the
T_out types is intended to give implementations the hooks necessary to free the inaccessible storage while converting from the
T_var types. The following examples demonstrate the compliant behavior:
Each call to the q function in the loop results in a memory leak because the caller is not invoking
string_free on the
out result. There are two ways to fix this, as shown below:
Using a plain char* for the
out parameter means that the caller must explicitly deallocate its memory before each reuse of the variable as an
out parameter, while using a
String_var means that any deallocation is performed implicitly upon each use of the variable as an
out parameter.
For parameters that are passed or returned as a pointer (T*) or as a reference to a pointer (
T*&), an application is not allowed to pass or return a NULL pointer; the result of doing so is undefined. In particular, a caller may not pass a NULL pointer under any of the following circumstances:
•
|
in and inout array (pointer to first element)
|
•
|
out and return variable-length struct
|
•
|
out and return variable-length union
|
•
|
out and return variable-length array, return fixed-length array
|
Table 13‑7 displays the mapping for the basic OMG IDL parameter passing modes and return type according to the type being passed or returned.
Table 13‑8 displays the same information for
T_var types.
Table 13‑8 is merely for informational purposes; it is expected that operation signatures for both clients and servers will be written in terms of the parameter-passing modes shown in
Table 13‑7, with the exception that the
T_out types will be used as the actual parameter types for all
out parameters.
It is also expected that T_var types will support the necessary conversion operators to allow them to be passed directly. Callers should always pass instances of either
T_var types or the base types shown in
Table 13‑7, and callees should treat their
T_out parameters as if they were actually the corresponding underlying types shown in
Table 13‑7.
In Table 13‑7, fixed-length arrays are the only case where the type of an
out parameter differs from a return value, which is necessary because C++ does not allow a function to return an array. The mapping returns a pointer to a
slice of the
array, where a slice is an array with all the dimensions of the original array
specified except the first dimension.
Table 13‑9 and
Table 13‑10 describe the caller’s responsibility for storage associated with
inout and
out parameters and for return results.
|
|
|
Caller allocates all necessary storage, except that which may be encapsulated and managed within the parameter itself. For inout parameters, the caller provides the initial value, and the callee may change that value. For out parameters, the caller allocates the storage but need not initialize it, and the callee sets the value. Function returns are by value.
|
|
Caller allocates storage for the object reference. For inout parameters, the caller provides an initial value; if the callee wants to reassign the inout parameter, it will first call CORBA::release on the original input value. To continue to use an object reference passed in as an inout, the caller must first duplicate the reference. The caller is responsible for the release of all out and return object references. Release of all object references embedded in other structures is performed automatically by the structures themselves.
|
|
For out parameters, the caller allocates a pointer and passes it by reference to the callee. The callee sets the pointer to point to a valid instance of the parameter’s type. For returns, the callee returns a similar pointer. The callee is not allowed to return a NULL pointer in either case.
|
|
For inout strings, the caller provides storage for both the input string and the char* pointing to it. Since the callee may deallocate the input string and reassign the char* to point to new storage to hold the output value, the caller should allocate the input string using string_alloc(). The size of the out string is, therefore, not limited by the size of the in string. The caller is responsible for deleting the storage for the out using string_free(). The callee is not allowed to return a NULL pointer for an inout, out, or return value.
|
|
For inout sequences and anys, assignment or modification of the sequence or any may cause deallocation of owned storage before any reallocation occurs, depending upon the state of the Boolean release parameter with which the sequence or any was constructed.
|
|
For out parameters, the caller allocates a pointer to an array slice, which has all the same dimensions of the original array except the first, and passes the pointer by reference to the callee. The callee sets the pointer to point to a valid instance of the array.
|