我已经读过aliged_alloc
的那个人,应该这样使用:
void* aligned_alloc( std::size_t alignment, std::size_t size );
它使用alloc
和alignment
返回我要指向size
的指针。
在我的代码中,我尝试使用它:
int *a = aligned_alloc(1024, 10*sizeof(a));
并
std::cout << alignof(a) << std::endl;
它给了我8。但是我希望结果是1024,因为我的对齐方式是1024。
我不明白什么?
答案 0 :(得分:5)
a
的对齐方式不是a
所指向的内存的对齐方式。 alignof(a)
给出的8值是该类型所需的对齐方式,而不是a
值的最大对齐方式。
执行alignof(a)
时,等同于执行alignof(int *)
,在编译器/计算机上对齐必须为8。
答案 1 :(得分:3)
_Alignof
运算符(alignof
宏扩展为该运算符)的计算结果是给定操作数的 type 类型的对齐要求,而不是它指向的内容( (如果是指针)。
它是在编译时求值的,因此,如果操作数是一个指针,则它无法知道它所指向的对象,如果有的话。
C standard中的6.5.3.4p3节规定:
_Alignof
运算符产生其操作数类型的对齐要求。不评估操作数,结果是 整数常量。当应用于数组类型时,结果是 元素类型的对齐要求。
C++ standard的第8.3.6节:
1
alignof
表达式产生其操作数类型的对齐要求。操作数应该是表示完整的type-id 对象类型或其数组,或对其中之一的引用 类型。2 结果是
std::size_t
类型的积分常数。3 将
alignof
应用于引用类型时,结果是引用类型的对齐方式。将alignof应用于数组时 类型,结果是元素类型的对齐方式。
答案 2 :(得分:0)
alignof
是静态运算符。它会为您提供对象类型的本机对齐方式。 alignof(a)
将是int*
指针的本机对齐方式,而alignof(*a)
将是int
的本机对齐方式。
aligned_alloc
不是编译时函数。它在运行时分配内存,并且该内存的对齐方式将是指针存储的地址中尾随零的计数的2(最容易/最有效的方法是使用gcc / clang提供的__builtin_ctz*
内置函数进行计数)。< / p>
摘要
#include <stdlib.h>
#include <stdio.h>
#include <stdalign.h>
int main()
{
int *a = (int*)aligned_alloc(1023,1);
printf("%zu %zu\n", alignof(a), alignof(*a));
printf("ctz=%u\n",__builtin_ctzll((unsigned long long)a));
printf("%llu\n",1ull<<__builtin_ctzll((unsigned long long)a));
}
在http://coliru.stacked-crooked.com/a/51606a7d251103a9上运行通常似乎返回指向2 ^ 12或2 ^ 13对齐的指针,这是可以的,因为这样的过度对齐的指针肯定也对齐了2 ^ 10(== 1024)。>
示例输出:
8 4
ctz=12
4096