鱼C论坛

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

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

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

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

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

x
#include<stdio.h>


typedef union{

        long i;
        char j[10];
        int k;

}DATE;

struct data{

        int m;//4
        DATE n;
        double i;//8
}test;

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

        printf_s("size of int = %d\n",sizeof(int));//4
        printf_s("size of long = %d\n",sizeof(long));//4
        printf_s("size of double = %d\n",sizeof(double));//8
        printf_s("size of float = %d\n",sizeof(float));//4
        printf_s("size of unsigned int = %d\n",sizeof(unsigned int));//4


}

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

使用道具 举报

 楼主| 发表于 2020-8-26 11:09:53 | 显示全部楼层
C:\Users\Administrator\Desktop\3.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-26 11:10:39 | 显示全部楼层
运行结果我在程序后面注释了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-26 11:22:06 | 显示全部楼层
int 4
DATE 4
double 8
4 + 12 = 16 刚好是8的倍数再加double的8等于24
想知道小甲鱼最近在做啥?请访问 -> 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了?
struct data{

        int m;//4
        DATE n;
        double i;//8
}test;
//修改一下,如下
struct data{

        int m;//4
        DATE n;
        char c;
        double i;//8
}test;
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-26 11:25:05 | 显示全部楼层
//这个的实际大小是10,long 是4; char j [10]是10;int k是4
//union以size最大的字段为union的大小,这里以 char j[10]为union的大小。
//32位系统内存对齐到4的倍数,因此扩大为12
typedef union{

        long i;
        char j[10];
        int k;

}DATE;

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

        int m;//4
        DATE n;
        double i;//8
}test;
想知道小甲鱼最近在做啥?请访问 -> 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的结果,必须是其内部最大成员的整数倍,不足的要补齐。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-26 11:31:21 | 显示全部楼层    本楼为最佳答案   
int DATE 4的倍数就可以存储加起来16 double 8的倍数的位置存储 前面加起来16刚好是8的倍数 就接着存放double的8 结果就为24了
想知道小甲鱼最近在做啥?请访问 -> 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
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

对的,你说的对,我懂了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

对的,但是我是64位机,对齐到是4的倍数,32位机我不太清楚
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-1-13 07:37

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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