引例

先看这样一段程序。

    // tStructSize.c#include<stdio.h>struct perInfo1{int num; // 4 byteschar name[10]; // 10 bytesdouble account; // 8 bytes};struct perInfo2{char name[10]; // 10 bytesdouble account; // 8 bytesint num; // 4 bytes};int main(){struct perInfo1 Tony1 = {1,"Tony",3.14159};int structSize1 = sizeof(struct perInfo1);struct perInfo2 Tony2 = {"Tony",3.14159,1};int structSize2 = sizeof(struct perInfo2);printf("Size : { int, char[10], double } = %d\n",structSize1);printf("Size : { char[10], double, int } = %d\n",structSize2);return 0;}

我们用sizeof函数查看一下结构体的大小。拍脑瓜一想 4+10+8=22,然而编译执行后输出却并非如此。那为什么是24和32呢?定义变量顺序的不同还会影响结构体的内存空间大小吗?

结构体的内存空间分配

先给出一个类似公式的结构体大小计算方法:

结构体大小 = 末尾成员偏移量+末尾成员大小+末尾填充字节数

然后我们解释以下perInfo1的分配内存过程,以便理解上面的“公式”,当我们定义一个这样的结构体时,操作系统会为该结构体分配一段连续的存储单元。

    struct perInfo1{int num; // 4 byteschar name[10]; // 10 bytesdouble account; // 8 bytes};struct perInfo1 Tony1 = {1,"Tony",3.14159};
  1. 首先为成员变量num分配 4 个字节的内存,它是该结构体的第一个成员变量,所以num的地址就是perInfo结构体的首地址,无偏移。如图(假设这是内存中的地址空间);

Tips 偏移量:这里可以简单理解为结构体内成员变量的地址距离结构体首地址的相地指数的大小。


  1. 然后开始考虑为name分配空间,name是由10个char型组成,可以认为是连续定义10个char变量。由于结构体在做字节对齐的时候有这样一个规则:每个成员相对于结构体首地址的偏移量必须是当前成员所占字节数的整数倍,如果不是,操作系统就会自动在前一个成员变量后自动填充补齐。
    当前偏移量是 4 ,是 1 (char类型)变量的的整数倍,不用填充,由如图分配。

  2. 为account分配空间:double型变量占用 8 个字节,而当前可分配地址的偏移量为 14 ,不是 8 的整数倍,需要做字节填充。

    填充后我们把偏移量为16的地址空间分配给account成员变量。这样就完成了结构体 perInfo1 的内存空间分配(perInfo2还存在另一个问题),大小为 24 字节。

  3. 在结构体定义完成前,还会进行如下判断:
    当前结构体的总大小是否为其最宽成员所占内存大小的整数倍,如果不是的话还要再将其填充成为整数倍。这也就是perInfo2的大小是 32 而不是 30 的原因了。


Tips perInfo2中当前结构体占位 30 字节,其最宽成员为 double 类型的 account 成员,占有 8 字节,因此要填充成 8 的整数倍 32 。


20210429更正图片如下。

  1. 我们也可以通过查看存储变量的地址来验证上面所述。
printf("Size : {int,char[10],double} = %d\n",structSize1);printf("-----{%d, %d, %d }\n",&(Tony1.num),&(Tony1.name),&(Tony1.account));printf("Size : {char[10],double,int} = %d\n",structSize2);printf("-----{%d, %d, %d }\n",&(Tony2.name),&(Tony2.account),&(Tony2.num));

.
.
.
.
.
.
桃花仙人种桃树,又摘桃花换酒钱_

C语言中结构体所占内存空间相关推荐

  1. c语言中申请内存并初始化,c语言中结构体的定义、初始化及内存分配

    #include struct person { char *name; int age; }; int main() { //结构体可以定义在函数内,也可以定义到函数外 //相当于全局变量与局部变量 ...

  2. C++_类和结构体所占内存大小,静态成员问题

    C++_类和结构体所占内存大小,静态成员问题 静态成员未初始化或者未调用(当然静态成员必须类外初始化才能调用)是不占内存的.静态成员不占类或结构体的内存 静态成员函数同样只声明未定义同样不占内存 指针 ...

  3. C 语言中结构体强制转换--实验

    2019独角兽企业重金招聘Python工程师标准>>> 对于C语言中结构体强制转换做了如下实验, 或许可以解惑一些问题 对于结构体, 我理解的属性有: 成员的顺序, 成员的类型,成员 ...

  4. java发送c语言结构体_C语言中结构体直接赋值?

    在C语言中结构体变量之间可以进行赋值操作吗? 简单结构体的赋值 先说结论:一般来说,C语言中的结构体变量可以用另一个变量对其进行赋值或初始化.简单结构体(不包含指针成员)直接赋值没有问题. 我们先下面 ...

  5. C语言中结构体直接赋值

    FROM:http://codewenda.com/c语言结构体直接赋值/ 在C语言中结构体变量之间可以进行赋值操作吗? 简单结构体的赋值 先说结论:一般来说,C语言中的结构体变量可以用另一个变量对其 ...

  6. c语言结构体成员变量私有化,C语言中结构体变量私有化详解

    C语言中结构体变量私有化详解 背景介绍 操作系统 : CentOS7.3.1611_x64 gcc版本 :4.8.5 什么是结构体? 在C语言中,结构体(struct)指的是一种数据结构,是C语言中聚 ...

  7. c语言定义学生结构体类型,C语言中结构体的三种定义方式

    c语言中结构体的定义: struct 结构体名{ 成员列表: ..... }结构体变量: 7.1.1 结构体类型变量的定义 结构体类型变量的定义与其它类型的变量的定义是一样的,但由于结构体类型需要针对 ...

  8. Go语言中结构体打Tag是什么意思?

    前言 哈喽,大家好,我是asong.今天想与大家分享Go语言中结构体标签是怎么使用的,以及怎样定制自己的结构体标签解析. 大多数初学者在看公司的项目代码时,看到的一些结构体定义会是这样的: type ...

  9. Go语言中结构体打 Tag 是什么意思?

    前言 哈喽,大家好,我是asong.今天想与大家分享Go语言中结构体标签是怎么使用的,以及怎样定制自己的结构体标签解析. 大多数初学者在看公司的项目代码时,看到的一些结构体定义会是这样的: type ...

  10. C语言中结构体标签的使用

    C语言中结构体标签的使用 我们都知道,结构体标签就是结构体的名称,为结构体命名可以方便我们在后续继续使用该结构体. 如 struct student {char* name;int age; }str ...

最新文章

  1. Oracle对数据的导出和导入,建立用户,删除用户以及其下的所有表
  2. 浅谈尾递归的优化方式
  3. ddr test DCD CFG file CBT
  4. 足坛绝代双骄全面数据对比,梅西30岁以后不如C罗?
  5. spring依赖注入_Spring的依赖注入陷阱
  6. android无感刷新下拉分页,GitHub - TakWolf/Android-RefreshAndLoadMore-Demo: 一种简单的并且优雅的方式实现下拉刷新和加载更多的分页效果。...
  7. 传统Web应用案例(采用服务端渲染)
  8. 苹果一键越狱工具_最新苹果越狱工具现世,可越狱所有iOS版本!
  9. [CareerCup] 8.10 Implement a Hash Table 实现一个哈希表
  10. 7-8 连续因子 (20 分)
  11. mysql 特殊函数_mysql 的特殊函数
  12. html页面锁屏,JavaScript网页锁屏效果源码实例
  13. ml302硬件手册_Cat.1模组ML302使用MQTT协议接入OneNet平台
  14. Mask rcnn介绍
  15. 简单的spring mvc实例
  16. 笔记本电脑秒便WIFI热点
  17. 【密码学/密码分析】基于TMTO的密码分析方法
  18. 日常生活收缩毛孔几个小妙招 - 生活至上,美容至尚!
  19. Spring MVC集成Swagger2.0
  20. Bitwise Exclusive-OR Sequence

热门文章

  1. 【wordpress】wordpress自己制作主题看这一篇就够了/常用函数/注意事项
  2. git fork 什么意思
  3. 银行核心业务系统性能测试方法
  4. Apollo 算法阅读之Public Road轨迹规划算法--路径规划(含源代码)
  5. 明尼苏达大学Transportation Research Data Lab (TDRL)交通数据读取
  6. 表示背景色彩的html是,[html颜色代码]HTML语言中,设置背景颜色的代码是?
  7. Android之BLE(低功耗)蓝牙开发
  8. 杨帅浙江大学计算机,2013届浙江大学优秀毕业研究生.DOC
  9. 第61篇:合并多个工作薄的所有工作表
  10. azure mysql on vnet_管理 VNet 终结点 - Azure CLI - Azure Database for MySQL | Microsoft Docs