C++ 中自定义 new 运算符有什么要求?

问题描述 投票:0回答:1

我试图了解 C++ 中自定义重载 new 运算符的真正要求是什么。 特别是关于返回指针的对齐,在没有任何对齐规范的情况下调用 new 运算符的情况下。

void* operator new(std::size_t sz)
{
}

我已经看到了这个预处理器值

__STDCPP_DEFAULT_NEW_ALIGNMENT__
。但是,尚不清楚这是否是所有内存的最小对齐值。

标准中还有一段文字说“分配函数”应该返回这样的指针:

...存储对于任何没有新扩展对齐且具有请求大小的对象进行对齐。

所以我的问题有两个:

  • 这个新运算符给定大小的最小对齐是多少?
  • 如果返回的指针的对齐方式小于该值,结果是什么?是UB吗?
c++ memory-management language-lawyer memory-alignment
1个回答
0
投票

cppreferences 指出:

此函数需要返回一个适当对齐的指针,以指向所请求大小的对象。

这几乎改写了您使用的标准报价。

基本上,你需要了解平台。通常,对齐对于“基本”项是需要/有用的,例如指针、整数或双精度数;更复杂的对象(例如结构)本身通常没有对齐要求,但需要适当对齐成员。这意味着编译器必须为结构假设合适的对齐方式,这通常是结构中可能存在的任何内容的对齐方式。

这句话基本上是说,如果您请求 4 个字节,则必须对其进行对齐,以便任何 4 字节对象都可以使用 - 就像整数或浮点数。如果它是一个 8 字节对象,您必须确保它适用于指针和双精度数。如果您有一个 16 字节对象,并且您的平台没有任何 16 字节原语,那么它基本上是一个结构,您需要将其对齐到至少满足上述 8 字节对象的要求 - 除非您的编译器另有说法,无论出于何种原因,更喜欢 16 字节对齐。


至于“如果未对齐会发生什么”——将其视为未定义的行为。根据编译器的不同,它可能会严重扰乱其结构填充,甚至将数据放置在您返回的块之前;根据CPU的不同,未对齐的数据项在最坏的情况下可能会导致崩溃,或者在更好的情况下导致严重的性能下降(尽管就我个人而言,我认为崩溃是最好的情况,因为它告诉我出了什么问题......) .

© www.soinside.com 2019 - 2024. All rights reserved.