以下合法的 C++ 是否具有明确定义的行为?
class my_class { ... };
int main()
{
char storage[sizeof(my_class)];
new ((void *)storage) my_class();
}
或者由于指针转换/对齐考虑,这是否有问题?
以下合法的 C++ 是否具有明确定义的行为?
class my_class { ... };
int main()
{
char storage[sizeof(my_class)];
new ((void *)storage) my_class();
}
或者由于指针转换/对齐考虑,这是否有问题?
是的,这是有问题的。您根本无法保证内存已正确对齐。
虽然存在各种技巧来获得正确对齐的存储,但最好使用 Boost's 或 C++0x's aligned_storage
,它们会对您隐藏这些技巧。
那么你只需要:
// C++0x
typedef std::aligned_storage<sizeof(my_class),
alignof(my_class)>::type storage_type;
// Boost
typedef boost::aligned_storage<sizeof(my_class),
boost::alignment_of<my_class>::value>::type storage_type;
storage_type storage; // properly aligned
new (&storage) my_class(); // okay
请注意,在 C++0x 中,使用属性,您可以这样做:
char storage [[align(my_class)]] [sizeof(my_class)];
As people have mentioned here, this won't necessarily work due to alignment restrictions. There are several ways to get the alignment right. First, if you have a C++0x-compliant compiler, you can use the alignof operator to try to force the alignment to be correct. Second, you could dynamically-allocate the character array, since memory from operator new is guaranteed to be aligned in such a way that anything can use it correctly. Third, you could try storing the character array in a union with some type that has the maximum possible alignment on your system; I believe that this article has some info on it (though it's designed for C++03 and is certainly not as good as the alignof operator that's coming out soon).
Hope this helps!
由于对齐,它至少是有问题的。
在大多数非英特尔架构上,代码将由于对齐错误而产生“总线错误”,或者由于修复未对齐的内存访问所需的处理器陷阱而变得非常慢。
在英特尔架构上,这通常会比平时慢一点。除非涉及某些 SSE 操作,否则它也可能崩溃。
如果有人想避免使用 Boost 或 C++1x,这个完整的代码可以在 GCC 和 MSVC 中运行。特定于 MSVC 的代码基于 Chromium 的aligned_memory.h。它比 GCC 版本稍微复杂一些,因为 MSVC__declspec(align(.))
只接受文字对齐值,并且可以使用模板特化来解决所有可能的对齐问题。
#ifdef _MSC_VER
template <size_t Size, size_t Align>
struct AlignedMemory;
#define DECLARE_ONE_ALIGNED_MEMORY(alignment) \
template <size_t Size> \
struct __declspec(align(alignment)) AlignedMemory<Size, alignment> { \
char mem[Size]; \
};
DECLARE_ONE_ALIGNED_MEMORY(1)
DECLARE_ONE_ALIGNED_MEMORY(2)
DECLARE_ONE_ALIGNED_MEMORY(4)
DECLARE_ONE_ALIGNED_MEMORY(8)
DECLARE_ONE_ALIGNED_MEMORY(16)
DECLARE_ONE_ALIGNED_MEMORY(32)
DECLARE_ONE_ALIGNED_MEMORY(64)
DECLARE_ONE_ALIGNED_MEMORY(128)
DECLARE_ONE_ALIGNED_MEMORY(256)
DECLARE_ONE_ALIGNED_MEMORY(512)
DECLARE_ONE_ALIGNED_MEMORY(1024)
DECLARE_ONE_ALIGNED_MEMORY(2048)
DECLARE_ONE_ALIGNED_MEMORY(4096)
#else
template <size_t Size, size_t Align>
struct AlignedMemory {
char mem[Size];
} __attribute__((aligned(Align)));
#endif
template <class T>
struct AlignedMemoryFor : public AlignedMemory<sizeof(T), __alignof(T)> {};
数组的char
大小可能未正确对齐myclass
。在某些架构上,这意味着访问速度较慢,而在其他架构上,这意味着崩溃。而不是char
,您应该使用对齐等于或大于 的类型struct
,这是由其任何成员的最大对齐要求给出的。
#include <stdint.h>
class my_class { int x; };
int main() {
uint32_t storage[size];
new(storage) my_class();
}
为了为一个my_class
实例分配足够的内存,我认为size
应该是sizeof(my_class) / sizeof(T)
,T
你使用哪种类型来获得正确的对齐。