放置新的并对齐可能的偏移内存

时间:2018-04-23 17:28:43

标签: c++ memory placement-new

我一直在阅读placement new,我不确定我是否会"#34;在适当的对齐方面,它是完全与否。

我已经编写了以下测试程序,试图将一些内存分配给一个对齐的位置:

#include <iostream>
#include <cstdint>
using namespace std;
unsigned char* mem = nullptr;

struct A
{
  double d;
  char c[5];
};

struct B
{
    float f;
    int a;
    char c[2];
    double d;
};

void InitMemory()
{
    mem = new unsigned char[1024];
}

int main() {
    // your code goes here

    InitMemory();

    //512 byte blocks to write structs A and B to, purposefully misaligned
    unsigned char* memoryBlockForStructA = mem + 1;
    unsigned char* memoryBlockForStructB = mem + 512;

    unsigned char* firstAInMemory = (unsigned char*)(uintptr_t(memoryBlockForStructA) + uintptr_t(alignof(A) - 1) & ~uintptr_t(alignof(A) - 1));
    A* firstA = new(firstAInMemory) A();

    A* secondA = new(firstA + 1) A();
    A* thirdA = new(firstA + 2) A();

    cout << "Alignment of A Block: " << endl;
    cout << "Memory Start: " << (void*)&(*memoryBlockForStructA) << endl;
    cout << "Starting Address of firstA:  " << (void*)&(*firstA) << endl;
    cout << "Starting Address of secondA: " << (void*)&(*secondA) << endl;
    cout << "Starting Address of thirdA: " << (void*)&(*thirdA) << endl;
    cout << "Sizeof(A): " << sizeof(A) << endl << "Alignof(A): " << alignof(A) << endl;
    return 0;
}

输出:

Alignment of A Block: 
Memory Start: 0x563fe1239c21
Starting Address of firstA:  0x563fe1239c28
Starting Address of secondA: 0x563fe1239c38
Starting Address of thirdA: 0x563fe1239c48
Sizeof(A): 16
Alignof(A): 8

输出似乎有效,但我仍然有一些问题。 我有一些问题是:

  • fourthAfifthA等等...都会对齐吗?
  • 是否有更简单的方法可以找到正确对齐的内存位置?
  • struct B的情况下,它被设置为不适合内存。我是否需要重建它以使最大的成员位于结构的顶部,最小的成员位于底部?或者编译器会自动填充所有内容,以便它的成员d不会被填写?

1 个答案:

答案 0 :(得分:0)

  

第四次A,第五次A等等也都会对齐吗?

是的,如果类型的对齐是大小的倍数 女巫(我认为)总是如此

  

是否有更简单的方法可以找到正确对齐的内存位置?

http://en.cppreference.com/w/cpp/language/alignas

http://en.cppreference.com/w/cpp/memory/align 正如丹姆所说。

  

在结构B的情况下,它被设置为不对内存友好。我是否需要重建它以使最大的成员位于结构的顶部,最小的成员位于底部?或者编译器会自动填充所有内容,以便它的成员d不会被填写?

如果你考虑的话,你应该重新组织。

我认为编译器不会为你重新组织结构中的元素。 因为通常在解释原始数据(来自文件,网络......)时,这些数据通常只被解释为结构,而不同的编译器重新组织可能会破坏代码。

我希望我的解释清楚,我没有犯任何错误