I'm working on some older code that uses ATL's CComBSTR
type. I'm changing it so that it will compile using Visual C++ Express Edition, which does not come with ATL. I used only a very small subset of CComBSTR
, so doing this is fairly simple.
However, when allocating the BSTR
memory block, I need to fill the first four bytes with a 4 byte length prefix. I'm concerned that if I use a new char[size]
expression to allocate the memory for the string, that I will cause alignment faults due to the allocated char
array not having the correct alignment for the four byte prefix.
Is there anything in the standard that states what alignment requirements the returned values of new
have? All I see in C++11 are:
5.3.4/1 [expr.new]
It is implementation-defined whether over-aligned types are supported (3.11).3.11/6 [basic.align]
The alignment requirement of a complete type can be queried using an alignof expression (5.3.6). Furthermore, the types char, signed char, and unsigned char shall have the weakest alignment requirement. [ Note: This enables the character types to be used as the underlying type for an aligned memory area (7.6.2).—end note ]
I find this slightly confusing -- "weakest alignment requirement" says to me "least strict constraint on alignment", but the note under this seems to indicate the standard means the opposite.
Am I safe using a new char[sizeof(uint32_t) + 2*(length + 1)]
buffer as a BSTR
like this?
EDIT: I just realized that in this specific case of BSTR
, one needs to use SysAllocString in order to allocate the string anyway; but I'm still interested in whether or not it is okay to use new
in this way.
It is an implementation detail, but MSVC uses the operating system allocators. HeapAlloc() for CRT allocations, CoTaskMemAlloc() for COM type wrappers like _bstr_t. They both align by 8, both in 32-bit and 64-bit code.
You should never allocate memory for BSTRs with the new operator, the COM allocator must be used to ensure that they get deallocated using the proper heap. Important in any interop scenario, which is where BSTR is used, it is a standard Automation type. CoTaskMemAlloc/Free() is required but always use the BSTR helper functions to ensure they get properly initialized. SysAllocString() and SysFreeString(). Use SysAllocStringLen() to deal with strings containing embedded zeros.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With