浅谈结构体如何分配内存

今天把操作符sizeof用了个遍,各种类型基本都用了,最后发现结构体类型最麻烦。下面直接进入主题:

(1)先是定义了如下结构体:

struct{
            char a;
            int i;
            double d;
            }text;

然后用sizeof(text),预期结果是1+2+8 = 11???如果这样想就错了,答案是16.

(2)然后,换一下变量的顺序:

struct{
            char a;

double d;
            int i;
           }text;

猜猜答案是多少?11?16?错,答案是24

(3)再换个顺序:

struct{

double d;
            char a;

int i;
            }text;

又开始猜答案了,11?16?24?这次终于蒙对了,答案是16

   也许有人会问,同一个结构体,就是变量顺序的不同,为什么大小会有如此大的差别?下面就慢慢来解释。

在存储过程中,为了提高CPU的存储速度,编译器会对变量的起始地址做“对齐”处理。VC规定结构体的各变量存放的起始地址相对于结构体的起始地址的偏移量必须是该变量的类型所占字节数的倍数,并且整个结构体的字节数必须是该结构体中占用空间最大的类型的字节数的整数倍。所以上述3个结构体实际分配情况如下:

(1)1000 1111 11111111(0表示补充位)

首先,为char类型的a分配,由于是第一个,相当于起始地址是0,是sizeof(char)的整数倍,分配一位;接着,为int类型的i分配,其字节数是4,与起始地址的偏移量是1,不是4的整数倍,于是补充3个填充位,再为i分配4位;最后,为double类型的d分配,其字节数是8,与起始地址的偏移量是8,刚好是整数倍,于是接着分配8位,整个结构体就占16位。

(2)1 0000000 11111111 1111 0000 (由于20不是8的整数倍,最后还会补充4位,共计24位)

(3)11111111 1000 1111(共计16位)

时间: 2024-10-07 22:05:57

浅谈结构体如何分配内存的相关文章

浅谈结构体

一.首先为什么会出现结构体呢?(这个问题得弄明白,学习的时候,要有打破砂锅问到底的精神,自己要多问个为什么是这样,把别人的东西变成自己的知识点) 在我们学习c语言的时候,,我们一般都会见到基本数据类型:int     char      float    double等等,但是在表示一些复杂的的数据,显然所学的基本数据类型是不够了,所以这个时候我们就引入结构体这种新的数据类型,来满足开发需要. 二.什么是结构体? 1.  简单的来说,结构体就是用户根据实际需求来定义自己的复合数据类型,我们还是来

结构体声明与内存对齐

1.结构体的声明: 1)struct Student{ int stu_id; char name[25] int age; char sex;  }; Student student1, student2; 2)struct Student{ int stu_id; char name[25] int age; char sex;  }student1,student2; 3)struct { int stu_id; char name[25] int age; char sex;  }stu

结构体所占内存大小

结构体所占内存大小划分原则: 1.划分字节,按照当前结构体中,字节数最大的类型作为划分单元.[这里面还有一些前提.下面的例子会详细说到] 2.以矩形块儿的形式划分. #include <stdio.h> /**划分示意图: 最小单元是 double所以 这个 地方按照8个字节作为最小单元来划分. */ struct student1 { double avgMark; int ID; }; /**划分示意图: 最小单元不能是数组这个地方的最小单元是 1个字节 */ struct student

【C语言】结构体中的内存对齐问题

话说大家有没有发现结构体中的内存对齐问题很有意思呢?我们这一次就一起研究一下这个问题为什么值得人探讨. 结构体内存对齐有三个原则; 1.数据成员对齐规则:结构(struct或联合union)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储). 2.结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储.(struct a里存有s

C语言结构体所占内存大小

用一道面试题题引入struct str1    {         char   a;         int    b;         float  c;     double d;  };char类型占用1个字节,int型占用4个字节,short类型占用2个字节,float占4字节,double占8字节:那么我们可能会犯一个错误就是直接1+4+2=7,认为该结构体占用7个字节.这是错的.百度一了下发现这是因为计算机中存在一种叫做内存对齐的机制导致了该结果的发生. 在计算机中通常会让CPU从

结构体变量的内存结构

在C语言中,在默认情况下,编译器规定各成员变量存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用的字节的倍数. 例如: struct MyStruct { double ddal: char dda: int type: }: 得到的结果为:16 所以,在计算结构体变量的大小时: ①上面的所有字节数的总和,必须是下一个类型的整数倍数. ②总字节数一定是最大类型的整数倍. 例题: char a: double b: int e: 得:20

浅谈android应用性能之内存(转)

如何测试一个APP的内存占用情况?一个APP占用的内存分哪些部分?如何检查一个APP是否存在内存泄漏? 一.Android内存介绍: 在java开发过程中,是通过new来为对象分配内存的,而内存的释放是由垃圾收集器(GC)来回收的,在开发的过程中,不需要显式的去管理内存,java虚拟机会自动帮我们回收内存.但是这样有可能在不知不觉中就会浪费了很多内存,最终导致java虚拟机花费很多时间去进行垃圾回收,更严重的是造成JVM的OOM. 二.APP占用的内存分哪些 Android系统中的内存和linu

浅谈对象的创建、内存布局和访问定位

在此简单的记录一下<深入理解Java虚拟机>第2章的2.3节内容. 对象的创建 这里的对象的创建是指普通的对象(不包括数组和Class对象).对象的创建简单来说就是执行new的时候,虚拟机做出对应的响应.让我们看看一下虚拟机创建对象的过程: 1.虚拟机遇到new指令时,首先尝试在常量池中定位到对应类的符号引用,并检查这个符号引用代表类是否已被加载.解析和初始化过.如果没有,那必须先执行相应的类加载过程(后续会写一下关于类加载的问题). 2.类加载检查通过后,为新生对象分配内存.对象内存的大小在

Android开发:浅谈MVP模式应用与内存泄漏

最近博主开始在项目中实践MVP模式,却意外发现内存泄漏比较严重,但却很少人谈到这个问题,促使了本文的发布,本文假设读者已了解MVP架构. 本文原创作者:xiong_it,链接:http://blog.csdn.net/xiong_it MVP简介 M-Modle,数据,逻辑操作层,数据获取,数据持久化保存.比如网络操作,数据库操作 V-View,界面展示层,Android中的具体体现为Activity,Fragment P-Presenter,中介者,连接Modle,View层,同时持有modl