本文介绍了使用展示位置新运算符时,我真的需要担心对齐吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我阅读了这个,但我是仍然不知道是否我不必担心放置新运算符返回的不一致的指针 - 如下例所示:

 类A {
public:
long double a;
long long b;
A():a(1.3),b(1234){}
};

char buffer [64];

int main(){
//(buffer + 1)有意使用错误对齐
A * a = new(buffer + 1)A
a->〜A();
}

__ alignof(A)== 4 (buffer + 1)未与 4 对齐。但一切都很好 - 完整的例子:



如果这取决于架构,那么我使用:linux / powerpc / g ++ 4.xx



[更新]发布此问题后,我阅读这篇文章: a href =http://virtrev.blogspot.de/2010/09/memory-alignment-theory-and-c-examples.html> http://virtrev.blogspot.de/2010/09/memory-alignment -theory-and-c-examples.html 。

解决方案


可能在我的情况下,唯一的缺点是性能损失,当您在缓冲区上调用placement new时:

  A * a = new(buf) 

您正在调用内置的 void * operator new(std :: size_t size,void * ptr)noexcept 定义:

返回的指针应该被适当地对齐,因此对于 void * operator new(std :: size_t size,void * ptr)noexcept 来返回一个非对齐指针这不会让脱离钩子:

因此,如果将未对齐的存储传递到一个放置新表达式,你违反存储是对齐的假设,结果是UB。






确实,在上面的程序中,如果用 __ m128 b 之后)替换 long long b #include< xmmintrin.h> ),则程序将按预期进行segfault。


I read this When should I worry about alignment? but I am still do not know if I have to worry about not aligned pointer returned by placement new operator - like in this example:

class A {
public:
   long double a;
   long long b;
   A() : a(1.3), b(1234) {}
};

char buffer[64];

int main() {
   // (buffer + 1) used intentionally to have wrong alignment
   A* a = new (buffer + 1) A();
   a->~A();
}

__alignof(A) == 4, (buffer + 1) is not aligned to 4. But everything works fine - full example here: http://ideone.com/jBrk8

If this depends on architecture then I am using: linux/powerpc/g++ 4.x.x.

[UPDATE] Just after posting this question I read this article: http://virtrev.blogspot.de/2010/09/memory-alignment-theory-and-c-examples.html.Maybe the only drawbacks in my case would be performance penalty, I mean unaligned access cost more than aligned?

解决方案

When you call placement new on a buffer:

A *a = new (buf) A;

you are invoking the built-in void* operator new (std::size_t size, void* ptr) noexcept as defined in:

The provisions of (3.7.4) include that the returned pointer should be suitably aligned, so it's fine for void* operator new (std::size_t size, void* ptr) noexcept to return a nonaligned pointer if one is passed in. This doesn't let you off the hook, though:

So if you pass unaligned storage to a placement-new expression you're violating the assumption that the storage is aligned, and the result is UB.


Indeed, in your program above, if you replace long long b with __m128 b (after #include <xmmintrin.h>) then the program will segfault, as expected.

这篇关于使用展示位置新运算符时,我真的需要担心对齐吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-31 00:31