C语言中结构体内存大小问题 -问答-阿里云开发者社区-阿里云

开发者社区> 问答> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

C语言中结构体内存大小问题

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个字节。

展开
收起
杨冬芳 2016-05-27 15:49:53 1995 0
1 条回答
写回答
取消 提交回答
  • 杨冬芳
    IT从业

    答: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 声明指针时,并不为指针分配空间。

    2019-07-17 19:18:05
    赞同 展开评论 打赏
问答分类:
相关产品:
问答排行榜
最热
最新
相关课程
更多
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载