【发布时间】: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
输出似乎是有效的,但我仍然有一些问题。 我的一些问题是:
-
fourthA、fifthA等...是否也会对齐? - 有没有更简单的方法可以找到正确对齐的内存位置?
- 在
struct B的情况下,它被设置为对内存不友好。我是否需要重建它以使最大的成员位于结构的顶部,而最小的成员位于底部?还是编译器会自动填充所有内容,使其成员d不会错位?
【问题讨论】:
-
@DanM。啊啊啊,太好了!我不知道它的存在。我只能找到假设缓冲区将是同质类型并建议使用 alignas 的示例。我一定会调查的。
-
B 的内部由于填充而正确对齐(假设 B 在对齐的位置构造)。在某些情况下,重新排列成员的顺序可能会使类占用更少的内存。
标签: c++ memory placement-new