include
typedef struct _tag_LinkList{
struct _tag_LinkList *header; //8
int a; //4
} TLinkList;
int main(int argc, const char * argv[]) {
// insert code here...
TLinkList List;
printf("ch所占字节的大小为:%lu\n",sizeof (List.a)); // 4
printf("header所在字节的大小为:%lu\n",sizeof (List.header)); //8
printf("TLinkList所占字节的大小为:%lu\n",sizeof (List)); //16
return 0;
}
在xcode7中,运行后,header占8个字节,a占用4个字节,但是整个结构体TlinkList占16个字节。
答:sizeof 运算符的结果部分地依赖于其作用的类型:
•对 char 或者类型为 char 的表达式执行 sizeof 运算,结果得 1;
•对引用类型执行 sizeof 运算得到被引用对象所占空间的大小;
•对指针执行 sizeof 运算得到指针本身所占空间的大小;
•对解引用指针执行 sizeof 运算得到指针指向的对象所占空间的大小,指针不需要有效;
•对数组执行 sizeof 运算得到整个数组所占空间的大小(sizeof 不会把数组转换成指针来处理,可以用数组的大小除以单个元素的大小得到数组中元素的个数)。
•对 string 对象或 vector 对象执行 sizeof 运算只返回该类型固定部分的大小(24),不会计算对象占用了多少空间;
此外求类的大小时遵循下面规则(只统计与类的实例有关的,只与类型相关的不统计):
•类的非静态成员数据的类型大小之和,也就是说静态成员数据不作考虑。
•普通成员函数与sizeof无关,调用普通成员函数只需要知道函数的地址即可,而这些地址只与类型相关,与类型的实例无关。
•虚函数由于要维护在虚函数表,所以要占据一个指针大小
•类的总大小也遵守类似 struct 字节对齐的调整规则
•空类的大小为 1(空类型的实例中不包含任何信息,但是声明空类的实例时,必须在内存中占有一定的空间,否则无法使用这些实例。占有空间数由编译器决定,一般是1)。
内存对齐、struct 结构
许多实际的计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的首地址的值是某个数k(通常它为4或8)的倍数,这就是所谓的内存对齐。
每个特定平台上的编译器都有自己的默认“对齐系数”(32位机一般为4,64位机一般为8)。我们可以通过预编译命令#pragma pack(k),k=1,2,4,8,16来改变这个系数,其中k就是需要指定的“对齐系数”;也可以使用#pragma pack()取消自定义字节对齐方式。
struct 或者 union 成员对齐规则如下:
•第一个数据成员放在offset为0的地方,每个成员按照对齐系数和自身占用字节数中,二者比较小的那个进行对齐;
•在数据成员完成各自对齐以后,struct或者union本身也要进行对齐,对齐将按照对齐系数和struct或者union中最大数据成员长度中比较小的那个进行;
•先局部成员对齐,然后再全局对齐。(memory_align.cpp)
此外,值得注意的是,enum 内部是 int 实现的,所以大小为 4。用 typedef 声明指针时,并不为指针分配空间。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。