字符数组作为新位置的存储 是具有良好行为的下列法律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(); },c++,pointers,placement-new,C++,Pointers,Placement New,或者这是因为指针投射/对齐的考虑而有问题吗?这至少是因为对齐而有问题 在大多数非英特尔体系结构上,由于错误对齐,代码将生成“总线错误”,或者由于修复未对齐内存访问所需的处理器陷阱,代码将非常慢 在英特尔体系结构上,这通常只会比平常慢一点。除非涉及某些SSE操作,否则它也可能崩溃。字符数组可能无法正确对齐myclass的大小。在某些体系结构上,这意味着访问速度变慢,而在另一些体系结构上,这意味着崩溃。您应该使用对齐方式等于或大于结构对齐方式的类型,而不是字符,该类型由其任何成员的最大对齐要求提供

或者这是因为指针投射/对齐的考虑而有问题吗?

这至少是因为对齐而有问题

在大多数非英特尔体系结构上,由于错误对齐,代码将生成“总线错误”,或者由于修复未对齐内存访问所需的处理器陷阱,代码将非常慢


在英特尔体系结构上,这通常只会比平常慢一点。除非涉及某些SSE操作,否则它也可能崩溃。

字符数组可能无法正确对齐
myclass
的大小。在某些体系结构上,这意味着访问速度变慢,而在另一些体系结构上,这意味着崩溃。您应该使用对齐方式等于或大于
结构
对齐方式的类型,而不是
字符
,该类型由其任何成员的最大对齐要求提供

#include <stdint.h>

class my_class { int x; };

int main() {
    uint32_t storage[size];
    new(storage) my_class();
}
#包括
类my_类{int x;};
int main(){
uint32_t存储[大小];
新建(存储)my_类();
}

要为一个
myu类
实例分配足够的内存,我认为
size
应该是
sizeof(myu类)/sizeof(T)
,其中
T
是用于获得正确对齐的类型。

是的,这是有问题的。您根本无法保证内存正确对齐

虽然存在各种技巧来获得正确对齐的存储,但最好使用Boost或C++0x的
对齐存储
,它们会对您隐藏这些技巧

那么你只需要:

// 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兼容的编译器,那么可以使用alignof运算符尝试强制对齐正确。其次,您可以动态分配字符数组,因为操作符new的内存保证以任何东西都可以正确使用的方式对齐。第三,您可以尝试将字符数组存储在具有系统上最大可能对齐的某种类型的联合中;我相信它有一些信息(尽管它是为C++03设计的,当然没有即将推出的alignof操作符好)


希望这有帮助

如果有人不想使用Boost或C++1x,那么这段完整的代码可以在GCC和MSVC中使用。MSVC特定代码基于Chromium的。它比GCC版本稍微复杂一点,因为MSVC的
\uuu 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)> {};
\ifdef\u MSC\u VER
模板
结构对齐内存;
#定义声明一个对齐的内存(对齐)\
模板\
结构uu declspec(align(alignment))AlignedMemory{\
charmem[Size]\
};
声明一个对齐的内存(1)
声明一个对齐的内存(2)
声明一个对齐的内存(4)
声明一个对齐的内存(8)
声明一个对齐的内存(16)
声明一个对齐的内存(32)
声明一个对齐的内存(64)
声明一个对齐的内存(128)
声明一个对齐的内存(256)
声明一个对齐的内存(512)
声明一个对齐的内存(1024)
声明一个对齐的内存(2048)
声明一个对齐的内存(4096)
#否则
模板
结构对齐内存{
charmem[Size];
}属性(对齐(对齐));
#恩迪夫
模板
struct AlignedMemoryFor:public AlignedMemory{};

对我来说,这很好。不,省略号在这种情况下是不合法的…(提示:如果你想问代码是否定义良好,必须先编译。)任何人请告诉我在现实编程世界中做上述事情有什么用。@GMan:我真希望你只是开玩笑。是的,良好定义取决于省略的部分,但问题很明显。@user430294@David Heffernan:目标基本上是为对象分配存储空间,但只在必要时构造对象。同时保留一个缓存友好的内存访问模式(因此没有动态分配)。“…其对齐方式等于或大于结构的对齐方式,这是由其任何成员的最大对齐要求给出的”我认为这并不能保证,对齐方式完全由实现定义。(也就是说,它的对齐不一定是最严格的成员的对齐。)而且,
int
可以大于32位。@GMan:你说得对。不过,它在大多数情况下都有效。在这里,有一个链接:谢谢,这是非常有用的知道。对不起,还不完全是:)据我所知,存储类型是某种内置整数类型。我如何使用它?我可以通过void*自由地转换到my_类类型吗?对不起,我的意思是:“自由地来回转换到指向my_类实例的指针”。。。或者类似的:)@bluescani:啊,对不起。我的答案是不完整的:生成的类型应该用作内存块,因此它应该是该存储器的地址。我已经修好了。
#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)> {};