C++ 什么';sizeof和alignof的区别是什么?
sizeof和alignof之间有什么区别C++ 什么';sizeof和alignof的区别是什么?,c++,c++11,sizeof,alignof,C++,C++11,Sizeof,Alignof,sizeof和alignof之间有什么区别 #include <iostream> #define SIZEOF_ALIGNOF(T) std::cout<< sizeof(T) << '/' << alignof(T) << std::endl int main(int, char**) { SIZEOF_ALIGNOF(unsigned char); SIZEOF_ALIGNOF(char);
#include <iostream>
#define SIZEOF_ALIGNOF(T) std::cout<< sizeof(T) << '/' << alignof(T) << std::endl
int main(int, char**)
{
SIZEOF_ALIGNOF(unsigned char);
SIZEOF_ALIGNOF(char);
SIZEOF_ALIGNOF(unsigned short int);
SIZEOF_ALIGNOF(short int);
SIZEOF_ALIGNOF(unsigned int);
SIZEOF_ALIGNOF(int);
SIZEOF_ALIGNOF(float);
SIZEOF_ALIGNOF(unsigned long int);
SIZEOF_ALIGNOF(long int);
SIZEOF_ALIGNOF(unsigned long long int);
SIZEOF_ALIGNOF(long long int);
SIZEOF_ALIGNOF(double);
}
#包括
#define SIZEOF_ALIGNOF(T)std::cout以字节为单位提供实际类型或类型实例的大小
提供给定类型的任何实例所需的以字节为单位的对齐方式。这两个运算符的作用完全不同sizeof
给出类型的大小(需要多少内存),而alignof
给出类型必须对齐的字节数。恰好您测试的原语有一个与其大小相同的对齐要求(如果您仔细考虑的话,这是有道理的)
考虑一下,如果使用结构,会发生什么:
struct Foo {
int a;
float b;
char c;
};
alignof(Foo)
将返回4。嗯,“内存”基本上是一个庞大的字节数组。然而,大多数较大的东西,如整数,需要超过1个字节来存储它们——例如,一个32位的值将使用4个连续字节的内存
现在,计算机中的内存模块通常不是“字节”;它们也用几个字节“并行”组织,就像4字节块一样
对于CPU来说,在读取整数之类的数据时,不“跨越”这样的块边界更容易=效率更高=性能更好:
memory byte 0 1 2 3 4 5 6 7 8 9 10 11
integer goooood
baaaaaaaaad
这就是“对齐”所说的:4的对齐意味着这种类型的数据应该(或必须,取决于CPU)从4的倍数开始存储
您发现sizeof==alignof不正确;试试结构。结构也将对齐(因为它们的单个成员需要在正确的地址上结束),但它们的大小将大得多。对于基本类型,alignof值与sizeof值相同
区别在于所使用的定义数据类型,如使用struct;对于一个例子来说
typedef struct { int a; double b; } S;
//cout<<alignof(s); outputp: 8;
//cout<<sizeof(S); output: 12;
typedef结构{inta;双b;}S;
//cout旧问题(虽然没有标记为已回答),但认为除了Christian Stieber的答案外,这个例子使区别更加明确。此外,Meluha的回答包含一个错误,因为sizeof(s)输出是16而不是12
// c has to occupy 8 bytes so that d (whose size is 8) starts on a 8 bytes boundary
// | 8 bytes | | 8 bytes | | 8 bytes |
struct Bad { char c; double d; int i; };
cout << alignof(Bad) << " " << sizeof(Bad) << endl; // 8 24
// | 8 bytes | | 8 bytes |
struct Good { double d; int i; char c; };
cout << alignof(Good) << " " << sizeof(Good) << endl; // 8 16
//c必须占用8个字节,以便d(大小为8)从8个字节的边界开始
//| 8字节| | 8字节| | 8字节|
结构错误{char c;double d;int i;};
cout对于提供的答案,似乎有一些关于对齐实际是什么的混淆。这种混淆可能是因为有两种对齐方式
1。成员一致性
这是一个定性的度量,说明对于结构/类类型中特定的成员顺序,实例的字节数有多大。通常,如果结构中的成员按字节大小降序排列(即最大的成员排在第一,最小的成员排在最后),编译器可以压缩结构/类实例。考虑:
struct A
{
char c; float f; short s;
};
struct B
{
float f; short s; char c;
};
两个结构包含完全相同的信息。为了这个例子;浮点类型需要4个字节,短类型需要2个字节,字符需要1个字节。但是,第一个结构A的成员顺序是随机的,而第二个结构B的成员顺序是根据字节大小(在某些体系结构上可能有所不同,在本例中,我假设采用4字节对齐的x86 intel CPU体系结构)。现在考虑结构的大小:
printf("size of A: %d", sizeof (A)); // size of A: 12;
printf("size of B: %d", sizeof (B)); // size of B: 8;
如果您希望大小为7个字节,那么您将假设使用1字节对齐将成员打包到结构中。虽然有些编译器允许这样做,但由于历史原因(大多数CPU使用DWORD(双字)或QWORD(四字)通用寄存器),通常大多数编译器使用4字节甚至8字节对齐
有两个填充机制在工作,以实现包装
首先,如果生成的字节大小小于或等于字节对齐方式,则每个字节大小小于字节对齐方式的成员将与下一个成员“合并”。在结构B中,成员s和c可以这样合并;它们的组合大小是s为2字节,c为1字节==3字节
sizeof
和alignof
之间有什么区别
两者都是运营商。两者都返回一种类型的size\u t
sizeof
是对象的大小(以“字节”为单位),即编码对象所需的内存空间
alignof
是对象的“字节”地址对齐要求。值为1表示没有对齐限制。2表示地址应为偶数地址。4表示地址应为四元地址。等等
当尝试不符合对齐要求的对象引用时,结果是未定义的行为。
示例:
. 访问可能会工作,但速度较慢。
. 访问尝试可能会终止程序
// Assume alignof(int) --> 2
char a[4]; // It is not known that `a` begins on an odd or even address
int *p = a; // conversion may fail
int d = *p; // *p is UB.
OP代码的扩展和输出示例
SIZEOF_ALIGNOF(double);
SIZEOF_ALIGNOF(complex double);
SIZEOF_ALIGNOF(div_t);
SIZEOF_ALIGNOF(max_align_t);
8/8
16/8
8/4
32/16
请使用结构而不是本机类型重试此操作。返回给定类型的任何实例所需的字节对齐方式(2的整数幂)sizeof
当然只是给出了大小,以字节为单位。也许值得一提——额外的一点——尽管x86在大多数情况下都会执行未对齐的读写操作(缓慢但正确),但有些体系结构要求所有操作都要对齐,甚至在x86中也有一些特殊情况必须对齐(我认为是SIMD指令)@ USE1494506-如果这个或任何其他答案正确地回答你的问题,考虑标记它是正确的。(当然,这完全是你的选择。不要因为别人这么说而被迫接受答案(例如,就像我现在说的那样))@Steve314:IIRC,SIMD指令(至少是浮点指令)有两种变体——对齐和未对齐。不过,我可能错了。对于要求所有操作一致的体系结构——大多数都要求一致(包括流行的MIPS和ARM);x86在这里是个例外。事实上
// Assume alignof(int) --> 2
char a[4]; // It is not known that `a` begins on an odd or even address
int *p = a; // conversion may fail
int d = *p; // *p is UB.
SIZEOF_ALIGNOF(double);
SIZEOF_ALIGNOF(complex double);
SIZEOF_ALIGNOF(div_t);
SIZEOF_ALIGNOF(max_align_t);
8/8
16/8
8/4
32/16