鱼C论坛

 找回密码
 立即注册
查看: 1182|回复: 10

[已解决]结构体内存对齐问题

[复制链接]
发表于 2020-8-26 11:06:39 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  1. #include<stdio.h>


  2. typedef union{

  3.         long i;
  4.         char j[10];
  5.         int k;

  6. }DATE;

  7. struct data{

  8.         int m;//4
  9.         DATE n;
  10.         double i;//8
  11. }test;

  12. void main()
  13. {
  14.         DATE max;
  15.         printf_s("sizeof max =%d\n",sizeof(max));//12
  16.         printf_s("size of struct data = %d\n",sizeof(struct data));//24

  17.         printf_s("size of int = %d\n",sizeof(int));//4
  18.         printf_s("size of long = %d\n",sizeof(long));//4
  19.         printf_s("size of double = %d\n",sizeof(double));//8
  20.         printf_s("size of float = %d\n",sizeof(float));//4
  21.         printf_s("size of unsigned int = %d\n",sizeof(unsigned int));//4


  22. }
复制代码


那个共用体的内存大小是12,然后下面的结构体中用那个定义了一个变量,下面的结果为什么是24,
double不是8个字节,不是有内存对齐吗?这个怎么解释?希望会的大佬能够解答一下,谢谢!
最佳答案
2020-8-26 11:31:21
int DATE 4的倍数就可以存储加起来16 double 8的倍数的位置存储 前面加起来16刚好是8的倍数 就接着存放double的8 结果就为24了
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-8-26 11:09:53 | 显示全部楼层
C:\Users\Administrator\Desktop\3.png
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-26 11:10:39 | 显示全部楼层
运行结果我在程序后面注释了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-26 11:22:06 | 显示全部楼层
int 4
DATE 4
double 8
4 + 12 = 16 刚好是8的倍数再加double的8等于24
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-26 11:24:37 | 显示全部楼层
对齐了啊?int m 起始地址为0,DATE n 起始位置是4,double i 起始位置是16

另外你的是32位系统吧?
32位系统字节对齐,针对4字节或8字节变量,起始地址需要能被4整除即可,因此就是24个字节

我的系统是64位,没法帮你具体验证,你看看下面这个,在你那里结果会是什么,24是变成28了,还是变成32了?
  1. struct data{

  2.         int m;//4
  3.         DATE n;
  4.         double i;//8
  5. }test;
  6. //修改一下,如下
  7. struct data{

  8.         int m;//4
  9.         DATE n;
  10.         char c;
  11.         double i;//8
  12. }test;
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-26 11:25:05 | 显示全部楼层

  1. //这个的实际大小是10,long 是4; char j [10]是10;int k是4
  2. //union以size最大的字段为union的大小,这里以 char j[10]为union的大小。
  3. //32位系统内存对齐到4的倍数,因此扩大为12
  4. typedef union{

  5.         long i;
  6.         char j[10];
  7.         int k;

  8. }DATE;

  9. //4+12+8 = 24,没毛病
  10. struct data{

  11.         int m;//4
  12.         DATE n;
  13.         double i;//8
  14. }test;
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-26 11:29:23 | 显示全部楼层
结构体内存分布三大原则:

原则1:数据成员对齐规则:结构(struct或联合union)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储,double为8字节,那么存放的位置从8的位数开始)。

原则2:结构体作为成员:如果一个结构里有其他结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储。(struct a里存有struct b,b里有char,int,double等元素,那b应该从8的整数倍开始存储。)

原则3:收尾工作:结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍,不足的要补齐。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-26 11:31:21 | 显示全部楼层    本楼为最佳答案   
int DATE 4的倍数就可以存储加起来16 double 8的倍数的位置存储 前面加起来16刚好是8的倍数 就接着存放double的8 结果就为24了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-26 11:59:42 | 显示全部楼层
sunrise085 发表于 2020-8-26 11:24
对齐了啊?int m 起始地址为0,DATE n 起始位置是4,double i 起始位置是16

另外你的是32位系统吧?

我的是64位机,你该完那个结果是32
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-26 12:01:01 | 显示全部楼层
baige 发表于 2020-8-26 11:22
int 4
DATE 4
double 8

对的,你说的对,我懂了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-26 12:05:34 | 显示全部楼层

对的,但是我是64位机,对齐到是4的倍数,32位机我不太清楚
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-7-6 20:34

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表