我正在处理一些使用 ATL 的 CComBSTR
类型的旧代码。我正在更改它,以便它可以使用 ATL 不附带的 Visual C++ Express Edition 进行编译。我只使用了 CComBSTR
的一个非常小的子集,所以这样做相当简单。
但是,在分配BSTR
内存块时,我需要用4字节长度的前缀填充前四个字节。我担心如果我使用 new char[size]
表达式为字符串分配内存,我会因为分配的 char
数组而不是导致对齐错误正确对齐四字节前缀。
标准中是否有任何内容说明 new
的返回值有哪些对齐要求?我在 C++11 中看到的是:
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 ]
我觉得这有点令人困惑——“最弱的对齐要求”对我来说是“对对齐的最不严格的约束”,但下面的注释似乎表明标准的意思相反。
像这样使用 new char[sizeof(uint32_t) + 2*(length + 1)]
缓冲区作为 BSTR
安全吗?
编辑:我刚刚意识到,在 BSTR
的这种特定情况下,无论如何都需要使用 SysAllocString 来分配字符串;但我仍然对以这种方式使用 new
是否合适很感兴趣。
最佳答案
这是一个实现细节,但 MSVC 使用操作系统分配器。 HeapAlloc() 用于 CRT 分配,CoTaskMemAlloc() 用于 COM 类型包装器,如 _bstr_t。在 32 位和 64 位代码中,它们都按 8 对齐。
您永远不应该使用 new 运算符为 BSTR 分配内存,必须使用 COM 分配器来确保使用正确的堆释放它们。在使用 BSTR 的任何互操作场景中都很重要,它是一种标准的自动化类型。 CoTaskMemAlloc/Free() 是必需的,但始终使用 BSTR 辅助函数来确保它们得到正确初始化。 SysAllocString() 和 SysFreeString()。使用 SysAllocStringLen() 处理包含嵌入零的字符串。
关于c++ - 标准全局默认运算符 new 的对齐限制是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13097268/