分配对齐结构的数组
Allocating an array of aligned struct
>我正在尝试分配一个结构数组,我希望每个结构都对齐到 64 个字节。
我试过这个(目前仅适用于 Windows),但它不起作用(我尝试使用 VS2012 和 VS2013):
struct __declspec(align(64)) A
{
std::vector<int> v;
A()
{
assert(sizeof(A) == 64);
assert((size_t)this % 64 == 0);
}
void* operator new[] (size_t size)
{
void* ptr = _aligned_malloc(size, 64);
assert((size_t)ptr % 64 == 0);
return ptr;
}
void operator delete[] (void* p)
{
_aligned_free(p);
}
};
int main(int argc, char* argv[])
{
A* arr = new A[200];
return 0;
}
断言((size_t)this % 64 == 0)
中断(模数返回 16)。如果结构仅包含简单类型,它看起来可以工作,但是当它包含std
容器(或其他一些 std 类)时会中断。
我做错了什么吗?有没有办法正确地做到这一点?(最好兼容 c++03,但任何适用于 VS2012 的解决方案都可以)。
编辑:正如Shokwav所暗示的那样,这是有效的:
A* arr = (A*)new std::aligned_storage<sizeof(A), 64>::type[200];
// this works too actually:
//A* arr = (A*)_aligned_malloc(sizeof(A) * 200, 64);
for (int i=0; i<200; ++i)
new (&arr[i]) A();
所以看起来它与使用new[]有关...我很好奇是否有人有解释。
我想知道为什么你需要如此巨大的对齐要求,而且要在结构中存储动态堆分配的对象。但你可以这样做:
struct __declspec(align(64)) A
{
unsigned char ___padding[64 - sizeof(std::vector<int>)];
std::vector<int> v;
void* operator new[] (size_t size)
{
// Make sure the buffer will fit even in the worst case
unsigned char* ptr = (unsigned char*)malloc(size + 63);
// Find out the next aligned position in the buffer
unsigned char* endptr = (unsigned char*)(((intptr_t)ptr + 63) & ~63ULL);
// Also store the misalignment in the first padding of the structure
unsigned char misalign = (unsigned char)(endptr - ptr);
*endptr = misalign;
return endptr;
}
void operator delete[] (void* p)
{
unsigned char * ptr = (unsigned char*)p;
// It's required to call back with the original pointer, so subtract the misalignment offset
ptr -= *ptr;
free(ptr);
}
};
int main()
{
A * a = new A[2];
printf("%p - %p = %dn", &a[1], &a[0], int((char*)&a[1] - (char*)&a[0]));
return 0;
}
我没有您的align_malloc和免费功能,所以我提供的实现是这样做的:
- 它
- 分配更大的内容以确保它适合 64 字节的边界
- 它计算从分配到最接近的 64 字节边界的偏移 量
- 它将"偏移量"存储在第一个结构的填充中(否则我每次都需要更大的分配空间)
- 这用于计算回指向 free() 的原始指针
输出:
0x7fff57b1ca40 - 0x7fff57b1ca00 = 64
警告:如果您的结构中没有填充,那么上面的方案将损坏数据,因为我将未对齐偏移量存储在将被内部成员的构造函数覆盖的位置。请记住,当你执行"new X[n]"时,"n"必须存储在"某处",因此在调用delete[]时,将对析构函数进行"n"调用。通常,它存储在返回的内存缓冲区之前(new 可能会分配所需的大小 + 4 来存储元素的数量)。这里的方案避免了这一点。
另一个警告:由于C++调用此运算符时,大小中包含一些额外的填充,用于存储数组的元素数,因此您可能仍会在对象的返回指针地址中获得"shift"。您可能需要考虑它。这就是 std::align 所做的,它占用额外的空间,像我一样计算对齐并返回对齐的指针。但是,您无法在 new[] 重载中同时完成这两项工作,因为从 new() 返回后会发生"计数存储"偏移。但是,您可以通过单个分配计算一次"计数存储"空间,并在 new[] 实现中相应地调整偏移量。
- 从函数中全局删除并重新实例化数组结构,而无需在编译时知道数组的大小
- 如何使用函数的输出初始化 const 数组结构字段?
- 传递数组结构、ofstream 和 interger 以运行
- 从文本文件中读取并输入到数组结构中,然后显示读取的数据C++
- 将文本文件读取到数组结构中
- C/C++中数组结构和数组结构的通用接口
- C++ MDC final-在字符类型的数组结构中按字母顺序对记录中的名称进行排序
- C++ 使用数组结构创建平衡的二叉搜索树
- C++:释放动态数组(结构成员)和指向此结构的指针的方法
- 使用 vector 在 c++ 中声明 3D 数组结构
- 数组结构无法正确打印
- 如何在C++中访问数组结构内部的数组结构
- CIN进入数组结构似乎什么也没输入
- ifstream将数组结构到txt文件中,然后尽可能将其提取为数组
- wlanapi-将WlanFreeMemory释放其WLAN_INTERFACE_INFO数组结构
- 显示数组结构 c++
- C++ 使用函数访问数组结构的方法是什么?
- 将庞大的数组结构复制到 GPU
- 如何封送包含字符矩阵的数组结构
- C++多维数组结构的对齐