【问题标题】:Placement new and aligning for possible offset memory放置新的并对齐可能的偏移内存
【发布时间】:2018-04-23 17:28:42
【问题描述】:

我一直在阅读placement new,我不确定在正确对齐方面我是否完全“理解”了它。

我编写了以下测试程序来尝试将一些内存分配给对齐的点:

#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 不会错位?

【问题讨论】:

  • @DanM。啊啊啊,太好了!我不知道它的存在。我只能找到假设缓冲区将是同质类型并建议使用 alignas 的示例。我一定会调查的。
  • B 的内部由于填充而正确对齐(假设 B 在对齐的位置构造)。在某些情况下,重新排列成员的顺序可能会使类占用更少的内存。

标签: c++ memory placement-new


【解决方案1】:

fourthA、fifthA 等……也会对齐吗?

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

有没有更简单的方法来找到正确对齐的内存位置?

是的

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

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

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

如果你考虑一下,你应该重新组织。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-20
    • 2017-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-20
    • 2011-04-30
    • 2018-05-04
    相关资源
    最近更新 更多