C中结构体的存储分配
对于C语言中结构体所占的存储空间的大小,也一直是笔试面试的常客,今天好好看了一下这方面,以前一直以为很清楚了,今天通过各种实际测试举例,发现原来还是没有搞透彻,好在现在是彻底懂了,所以和大家分享,希望能有所帮助。
提到结构体,相信大家都知道元素存储要对齐,话是没有错,只是这个“对齐”里面包含了很多微妙的东西。首先详细的给出结构体内存分配的原则吧:编译器按照成员列表顺序一个接一个地给每个成员分配内存。只有当存储成员时需要满足正确的边界对齐要求时,成员之间才可能出现用于填充的额外内存空间。接下来我们来慢慢理解这句话。
sizeof操作符能够得出一个结构的整体长度,包括因边界对齐而跳过的那些字节。所以一般都用sizeof来计算其所占存储空间。来看下面的例子:
struct test1
{
int a;
char b[];
char c;
};
计算可以得到test1占16个字节。原因是a占4个字节(32位机,int占4个字节),b和c分别占9个字节和1个字节,加起来10个字节,与a对齐,则需要12个字节,所以总共需要16个字节。这个例子就是我们最熟悉的,接下来看一下个。
struct test2
{
char b[];
int a;
char c;
};
计算可以得到test2占20个字节。比较test1和test2可以发现仅仅将a和b的位置换了一下,为什么结果会不同呢?这就是前面定义中所说的顺序的问题。int为最大字节,一开始分配9个字节,然后是a,为了对齐,这时候应该是12+4个字节,后面又来一个char,为了对齐加4,所以总共是20个字节。而test1因为后面两个类型一致,所以可以和在一起分配,然后对齐。
接下来我们在加大难度,看如下例子:
struct test3
{
char b[];
int a;
char c;
double d;
};
按照上面的逻辑,b占9个字节,a占4个字节,为了和a对齐,所以此时应该是12+,接着是c为1个字节总共为12++=,然后是d为8个字节,为了和8字节对齐,则应该为24+=32个字节,即最终结果为32个字节。变换一下顺序,得到如下例子:
struct test4
{
char b[];
int a;
double d;
char c;
};
同样的,b和a占据12+4个字节,d为8个字节,则应该是16+=,加上最后的一个字节,为了对齐,总共也是24+=32个字节。这里需要注意的是,若数组b元素改为13,则为了对齐,d前面应该是16+4,然后遇到d,对齐后为24+8,在加上最后的8个字节,应该为40个字节。
再来看一个:
struct test4
{
double d;
char b[];
int a;
char c;
};
d占8个字节,b占9个字节,后面是int,为了对齐,加上a应该是20+,再加上1个字节,为了和最大的double对齐,所以应该是20++=32个字节。
好了,通过列举这么多不同的例子,最终目标只有一个,是真的搞清楚某个结构体占据的空间大小。通过上面的例子,我总结了以下几点。
)首先,看该结构体中最大的“基元素”(这是我杜撰的,就是说基本元素类型最大的是哪个,例如test1和test2都是int,而test3和test4都是double,而不是看数组总共所占据的大小),找到这个以后,结构体所占据的空间的大小一定要是该基本元素所占空间大小的整数倍。
)接着,按顺序将元素进行排列。前一元素要与后一元素对齐,如果后一元素的“基元素”比前一个大,则前一元素需要调整大小,即对齐该后一元素。
)最后将得到的字节大小加起来,跟最大的基元素对齐,即得到最终的所占存储空间大小。
如果要确定结构中某个成员的实际位置,可以使用offsetof宏(stddef.h)offsetof(type,member)。type是结构的类型,member是该结构的成员名,表达式的结构是一个sizeof_t值。表示该指定成员的存数位置(离该结构体存储的起始位置)。
另外还有一点值得一提的是,当结构体里面包含另一结构体时,直接将该结构体中的内容代换进去,计算其总的存储空间即可。
http://blog.sina.com.cn/s/blog_67b077fe0101844k.html

C中结构体的存储分配的更多相关文章

  1. C#中结构体和类的区别

    结构体和类同样能够定义字段,方法和构造函数,都能实例化对象,这样看来结构体和类的功能好像是一样的了,但是他们在数据的存储上是不一样的 C#结构体和类的区别问题:这两种数据类型的本质区别主要是各自指向的 ...

  2. C语言中结构体对齐问题

    C语言中结构体对齐问题 收藏 关于C语言中的结构体对齐问题 1,比如: struct{short a1;short a2;short a3;}A;struct{long a1;short a2;}B; ...

  3. (一)一个工作任务引起的乱战——c#中结构体与byte[]间相互转换

    一个工作任务涉及到c#与c++系统间的udp通信,处理了蛮长时间没有完成任务,但是期间接触到不少小知识点.本人是初接触c#,c++语言没有接触过.可能写的东西都很小儿科,暂且记录下来当工作日记把. 先 ...

  4. 《挑战30天C++入门极限》C/C++中结构体(struct)知识点强化

        C/C++中结构体(struct)知识点强化 在上一个教程中我们已经简单的阐述了什么是结构体了,为了进一部的学习结构体这一重要的知识点,我们今天来学习一下链表结构. 结构体可以看做是一种自定义 ...

  5. C语言中结构体内存存储方式

    C语言中结构体内存存储方式 结构体的默认存储方式采用以最大字节元素字节数对其方式进行对齐,例如一个结构体中定义有char.int类型元素,则结构体存储空间按照int类型占用字节,如果还有double类 ...

  6. STM32L0系列EEPROM中结构体的读取

    在STM32L0中操作EEPROM本来参考了上篇操作FLASH的方法,多多少少都有些问题.我觉得可能是结构体在转换成其他变量的时候出了问题. 比如下面这段代码,在Windows上可以正常运行(使用g+ ...

  7. C语言中结构体赋值问题的讨论

    今天帮师姐调一个程序的BUG,师姐的程序中有个结构体直接赋值的语句,在我印象中结构体好像是不能直接赋值的,正如数组不能直接赋值那样,我怀疑这个地方有问题,但最后证明并不是这个问题.那么就总结一下C语言 ...

  8. OC中结构体作为对象属性

    在OC中结构体有时候也作为对象的属性 类的定义 #import <Foundation/Foundation.h> typedef struct{ int year; int month; ...

  9. C C++ 中结构体与类

    先来说说C和C++中结构体的不同 a) C语言中的结构体不能为空,否则会报错 1>d:\myproject\visual studio 2013\projects\myc++\main.c(71 ...

随机推荐

  1. 获取网站资源 getResourceAsStream

    获取网站资源(重点) public void doGet(HttpServletRequest request, HttpServletResponse response)throws Servlet ...

  2. 【LeetCode】107. Binary Tree Level Order Traversal II (2 solutions)

    Binary Tree Level Order Traversal II Given a binary tree, return the bottom-up level order traversal ...

  3. xp 如何打开(进行)远程桌面连接

    http://apps.hi.baidu.com/share/detail/31102654http://help.360.cn/5030804/40072526.htmlhttp://hi.baid ...

  4. linux服务器的Gzip文件压缩方法[转]

    一.gzip介绍 gzip是GNU zip的缩写,它是一个GNU自由软件的文件压缩程序,也经常用来表示gzip这种文件格式.软件的作者是Jean-loup Gailly和Mark Adler.1992 ...

  5. php 文件上传,下载

    文件下载: html: <html> <body> <a href="1.rar">下载1.rar</a> <br /> ...

  6. Linux内核(1) - Kernel地图:Kconfig与Makefile

    Makefile不是Make Love 从前在学校,混了四年,没有学到任何东西,每天就是逃课,上网,玩游戏,睡觉.毕业的时候,人家跟我说Makefile我完全不知,但是一说Make Love我就来劲了 ...

  7. 基于配置的Spring MVC3

    网上查找的spring mvc3大部分都是基于注射的方式,总感觉注射有点怪怪.不利于后期扩展和项目管理,于是特意写下这篇基于xml配置的Spring MVC3.以供大家參考. 怎么建立web项目和下载 ...

  8. EXTJS 5 学习笔记1 - Class System

    1. Name Conventions 命名规范      1) Classes 类          a. 类名只能包含数字字母 only contain alphanumeric characte ...

  9. SqlMapConfig.xml中的setting属性 Ibatis mybatis

    <settingscacheModelsEnabled="true"lazyLoadingEnabled="false"enhancementEnable ...

  10. elk中文教程

    https://kibana.logstash.es/content/elasticsearch/monitor/logging.html ELK 实战之Elasticsearch ELK 地址:ht ...