Partager via


Responsibility for Freeing Memory

When the consumer calls a method that gets or sets data, such as IRowset::GetData, IRowsetChange::SetData, or ICommand::Execute, it passes a pointer to a consumer-owned data buffer. The consumer is responsible for allocating and freeing memory for this buffer. The provider can only read this memory. It must not free this memory nor should it assume that this memory exists after the method returns.

If the type indicator is DBTYPE_BSTR or is combined with DBTYPE_BYREF, DBTYPE_ARRAY, or DBTYPE_VECTOR, the consumer's memory contains a pointer to a separately allocated data buffer. This separate data buffer actually contains the data value, as distinct from the length and status, for the column or parameter. For example, if the type indicator is DBTYPE_BYREF | DBTYPE_STR, the data value in the consumer's memory is a pointer to an ANSI string. If the type indicator is DBTYPE_BSTR, the data value is a BSTR, which is a pointer to a length-prefixed, null-terminated string of Unicode characters. The remainder of this section discusses how this separate data buffer is managed.

Note

A consumer can bind an input/output parameter with a type indicator of DBTYPE_BSTR or with a type indicator that is combined with DBTYPE_BYREF, DBTYPE_ARRAY, or DBTYPE_VECTOR. If the consumer does this, and when the provider returns the output value for the parameter, the provider overwrites the pointer in the consumer's buffer that points to the input value. To ensure access to the input value after the provider returns the output value ? for example, to free it ? the consumer should keep a separate copy of the pointer to the input value.

When getting data, the provider is responsible for allocating the separate data buffer. The method by which the provider allocates this memory and the responsibility for freeing it is determined by the dwMemOwner element of the applicable binding.

If dwMemOwner is DBMEMOWNER_PROVIDEROWNED, the provider allocates the memory and frees it by whatever method it chooses. The consumer can only read the memory and must not free it or write to it. The memory is part of the rowset's copy of the row, which saves the provider from separately allocating it and the consumer from freeing it. Consumers usually use provider-owned memory when they need fast, read-only access to the data. For more information about provider-owned memory, see dwMemOwner in DBBINDING Structures.

If dwMemOwner is DBMEMOWNER_CLIENTOWNED, the provider allocates and the consumer frees the memory as noted in the following list. Although the provider must not access this memory after the method returns, the consumer can access it at any time until it is freed. Consumers use consumer-owned memory when they need their own copy of the data and when they send data to the provider.

  • DBTYPE_BSTR ? BSTRs are allocated and freed by calling COM string manipulation functions such as SysAllocString and SysFreeString. For more information, see Appendix A: Data Types in Appendix A: Data Types.

  • DBTYPE_BYREF ? Memory is allocated and freed by calling the COM task allocator's IMalloc methods.

  • DBTYPE_ARRAY ? SAFEARRAY structures are allocated and freed by calling COM array manipulation functions such as SafeArrayCreate and SafeArrayDestroy. For more information, see Appendix A: Data Types in Appendix A: Data Types.

  • DBTYPE_VECTOR ? Memory is allocated and freed by calling the COM task allocator's IMalloc methods.

The consumer can mix bindings in which pointers to the data and the data itself are returned. For example, suppose a rowset has two columns containing ANSI strings, one of which has a maximum length of 10 characters and the other a maximum length of 32,000 characters. The consumer might choose to get the first string directly in its buffer (wType is DBTYPE_STR, cbMaxLen is 11, and dwMemOwner is DBMEMOWNER_CLIENTOWNED) and get a pointer to the provider's data cache for the second string (wType is DBTYPE_STR | DBTYPE_BYREF, and dwMemOwner is DBMEMOWNER_PROVIDEROWNED).

The consumer can also mix bindings in which the consumer and provider own the memory. For example, suppose a rowset includes two columns that contain ANSI strings with a maximum length of 32,000 characters but only one column is updatable. The consumer might choose to get pointers to both strings (wType is DBTYPE_STR | DBTYPE_BYREF) but to use consumer-owned memory (dwMemOwner is DBMEMOWNER_CLIENTOWNED) for the updatable string and provider-owned memory (dwMemOwner is DBMEMOWNER_PROVIDEROWNED) for the read-only string.

This topic is a part of: