C中结构体的存储分配
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中结构体的存储分配的更多相关文章
- C#中结构体和类的区别
结构体和类同样能够定义字段,方法和构造函数,都能实例化对象,这样看来结构体和类的功能好像是一样的了,但是他们在数据的存储上是不一样的 C#结构体和类的区别问题:这两种数据类型的本质区别主要是各自指向的 ...
- C语言中结构体对齐问题
C语言中结构体对齐问题 收藏 关于C语言中的结构体对齐问题 1,比如: struct{short a1;short a2;short a3;}A;struct{long a1;short a2;}B; ...
- (一)一个工作任务引起的乱战——c#中结构体与byte[]间相互转换
一个工作任务涉及到c#与c++系统间的udp通信,处理了蛮长时间没有完成任务,但是期间接触到不少小知识点.本人是初接触c#,c++语言没有接触过.可能写的东西都很小儿科,暂且记录下来当工作日记把. 先 ...
- 《挑战30天C++入门极限》C/C++中结构体(struct)知识点强化
C/C++中结构体(struct)知识点强化 在上一个教程中我们已经简单的阐述了什么是结构体了,为了进一部的学习结构体这一重要的知识点,我们今天来学习一下链表结构. 结构体可以看做是一种自定义 ...
- C语言中结构体内存存储方式
C语言中结构体内存存储方式 结构体的默认存储方式采用以最大字节元素字节数对其方式进行对齐,例如一个结构体中定义有char.int类型元素,则结构体存储空间按照int类型占用字节,如果还有double类 ...
- STM32L0系列EEPROM中结构体的读取
在STM32L0中操作EEPROM本来参考了上篇操作FLASH的方法,多多少少都有些问题.我觉得可能是结构体在转换成其他变量的时候出了问题. 比如下面这段代码,在Windows上可以正常运行(使用g+ ...
- C语言中结构体赋值问题的讨论
今天帮师姐调一个程序的BUG,师姐的程序中有个结构体直接赋值的语句,在我印象中结构体好像是不能直接赋值的,正如数组不能直接赋值那样,我怀疑这个地方有问题,但最后证明并不是这个问题.那么就总结一下C语言 ...
- OC中结构体作为对象属性
在OC中结构体有时候也作为对象的属性 类的定义 #import <Foundation/Foundation.h> typedef struct{ int year; int month; ...
- C C++ 中结构体与类
先来说说C和C++中结构体的不同 a) C语言中的结构体不能为空,否则会报错 1>d:\myproject\visual studio 2013\projects\myc++\main.c(71 ...
随机推荐
- ArchLinux新版本(pacstrap安装)及国内较优源推荐
下载安装镜像和配置虚拟机都略过. 进入安装模式以后第一件事是要进行分区,分区很重要,怎么分区是由后面的grub的模式来决定的.grub有3种模式,分别对应grub-bios-gpt,grub-bios ...
- HDUOJ----Eddy's research I
Eddy's research I Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
- linux 常用awk命令
linux awk命令详解awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每 ...
- OGG_GoldenGate目标端库级别数据初始化(案例)
2014-03-07 Created By BaoXinjian
- DBA_Oracle Erp R12系统文件结构(概念)
20150609 Created By BaoXinjian
- X86 寻址方式、AT&T 汇编语言相关知识、AT&T 与 Intel 汇编语言的比较、gcc 嵌入式汇编
注:本分类下文章大多整理自<深入分析linux内核源代码>一书,另有参考其他一些资料如<linux内核完全剖析>.<linux c 编程一站式学习>等,只是为了更好 ...
- SVNserver搭建
SVN是Subversion的简称,是一个开放源码的版本号控制系统. 它由server和client组成,今天就带大家一起在server端搭建一个server. 前提:安装server端:Visual ...
- 目的可疑,但方法非常值得学习的书——leo鉴书56
书中提到写作手法绝对值得学习,为此能够打四颗星. 作者是个买直销产品的.靠写字让别人买自己的东西.当中特别强调了卖的多是太空时代的产品,意思就是读者非常可能并不须要,多半是被眼花缭乱的广告词儿骗了 ...
- session和cookie的联系
前提: 一.cookie机制 正统的cookie分发是通过扩展HTTP协议来实现的,服务器通过在HTTP的响应头中加上一行特殊的指示以提示浏览器按照指示生成相应的cookie.然而纯粹的客户端脚本如J ...
- 在Visual Studio中使用NuGet管理项目库
NuGet是用来管理项目中引用的各个组件插件什么什么东西的东西,最近使用以后发现对于项目引用的维护非常方便. 暂时转一篇MSDN的文章,其实这个文章的内容就够了: http://msdn.micros ...