请选择 进入手机版 | 继续访问电脑版

硬汉嵌入式论坛

 找回密码
 立即注册
查看: 6475|回复: 15
收起左侧

结构体变量占用多少字节问题

  [复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
105942
QQ
发表于 2018-8-22 16:24:50 | 显示全部楼层 |阅读模式
首先明白一点,结构体里面的变量是什么类型,此变量的位置就是至少要几字节对齐,所以就存在结构体实际占用大小不是这些变量之和。

typedef struct
{
        uint8_t a;
        uint16_t b;
        uint32_t c;
        uint64_t d;        
}info;

这种定义,info占用了16字节,a单字节对齐,b是两字节对齐,而c要是4字节对齐,从出现b定义完毕后空出来1个字节未被使用。d是8字节对齐,这样就是16字节。

而我们切换下变量定义顺序
typedef struct
{
        uint16_t b;
        uint32_t c;
        uint64_t d;        
        uint8_t  a;
}info;

这种定义就要占用24字节,b占用2字节对齐,c需要4字节对齐,这样就空出来2两个字节未使用,d占用8字节,最后一个a占用了8字节。


如果想定义几个变量就几个字节,变量前面加前缀__packed即可。

不管是上面那种定义方式,都是占用15个字节。

__packed typedef struct
{
        uint8_t a;   1个
        uint16_t b; 2个
        uint32_t c; 4个
        uint64_t d; 8个        
}info;


回复

使用道具 举报

39

主题

926

回帖

1048

积分

至尊会员

积分
1048
发表于 2018-8-22 19:17:45 | 显示全部楼层
那个a占8字节不能理解。然道结构体会按最大字节的变量来对齐?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
105942
QQ
 楼主| 发表于 2018-8-23 01:43:30 | 显示全部楼层
ghslfgkkl88 发表于 2018-8-22 19:17
那个a占8字节不能理解。然道结构体会按最大字节的变量来对齐?

这个得找下MDK的help文档看看了,估计是从第一个结构体成员开始判断,字节对齐逐次递增,比如遇到u16,后面就2字节对齐,遇到u32后面就4字节对齐,遇到u64,后面就8字节对齐,这个判断不知道对不对,后面验证下。
回复

使用道具 举报

39

主题

926

回帖

1048

积分

至尊会员

积分
1048
发表于 2018-8-23 10:02:46 | 显示全部楼层
eric2013 发表于 2018-8-23 01:43
这个得找下MDK的help文档看看了,估计是从第一个结构体成员开始判断,字节对齐逐次递增,比如遇到u16,后 ...

我昨天搜索了一下,说是结构体的体积,会是其中最大字节变量的整数倍
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
105942
QQ
 楼主| 发表于 2018-8-23 11:45:14 | 显示全部楼层
ghslfgkkl88 发表于 2018-8-23 10:02
我昨天搜索了一下,说是结构体的体积,会是其中最大字节变量的整数倍

对,还真有可能有,测试了个,就是16字节。
typedef struct
{
    uint8_t b;
    uint64_t d;       
}info;
回复

使用道具 举报

39

主题

926

回帖

1048

积分

至尊会员

积分
1048
发表于 2018-8-23 13:51:52 | 显示全部楼层
eric2013 发表于 2018-8-23 11:45
对,还真有可能有,测试了个,就是16字节。
typedef struct
{

以前都没注意这些,幸好有这个帖子
回复

使用道具 举报

3

主题

24

回帖

33

积分

新手上路

积分
33
发表于 2018-8-23 15:59:53 | 显示全部楼层
本帖最后由 confidentlin 于 2018-8-23 16:04 编辑

内存对齐的规则
1、 对于结构的各个成员,第一个成员位于偏移为0的位置,以后每个数据成员的偏移量必须是min(#pragma pack()指定的数,这个数据成员的自身长度) 的倍数。
2、 在数据成员完成各自对齐之后,结构(或联合)本身也要进行对齐,对齐将按照min(#pragma pack指定的数值和结构(或联合)最大数据成员长度)的倍数进行。

#pragma pack(n) 表示设置为n字节对齐。#pragma pack(1)就是按字节对齐,IAR #pragma pack(n)默认好像是8

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
105942
QQ
 楼主| 发表于 2018-8-23 17:16:21 | 显示全部楼层
confidentlin 发表于 2018-8-23 15:59
内存对齐的规则:1、 对于结构的各个成员,第一个成员位于偏移为0的位置,以后每个数据成员的偏移量必须是m ...

回复

使用道具 举报

0

主题

2

回帖

2

积分

新手上路

积分
2
发表于 2018-8-23 17:38:07 | 显示全部楼层
ghslfgkkl88 发表于 2018-8-22 19:17
那个a占8字节不能理解。然道结构体会按最大字节的变量来对齐?

内存对齐的规则:

起始地址为该变量的类型所占的整数倍,若不足则不足部分用数据填充至所占内存的整数倍。
该结构体所占内存为结构体成员变量中最大数据类型的整数倍。

是不是因为这个规则
回复

使用道具 举报

0

主题

9

回帖

9

积分

新手上路

积分
9
发表于 2019-1-15 19:47:47 | 显示全部楼层
confidentlin 发表于 2018-8-23 15:59
内存对齐的规则:1、 对于结构的各个成员,第一个成员位于偏移为0的位置,以后每个数据成员的偏移量必须是m ...

之前就是知道四字节对齐,这次算是从根本上知道了,多谢
回复

使用道具 举报

1

主题

103

回帖

106

积分

初级会员

积分
106
发表于 2019-6-19 16:22:09 | 显示全部楼层
__packed 在哪个文件,加了后报错了
回复

使用道具 举报

1

主题

103

回帖

106

积分

初级会员

积分
106
发表于 2019-6-19 16:40:14 | 显示全部楼层
typedef struct
{
    unsigned int  task_headPosition;   
    unsigned int  task_tailPosition;   
    unsigned char task_ringBuf[BUFFER_MAX];        
} task_ringBuffer_t;

用同一个结构体模型,我想定义多个不同的结构体,但是里面数组的元素个数不同。目前只能定义一种长度 BUFFER_MAX 为固定的个数。

比如:

task_ringBuffer_t    task_key;       task_key.task_ringBuf[ ]     我想只有7个元素。
task_ringBuffer_t    task_usart;     task_usart.task_ringBuf[  ]     我想只有1024个元素。

有什么好的解决方式了?

回复

使用道具 举报

39

主题

926

回帖

1048

积分

至尊会员

积分
1048
发表于 2019-6-19 18:19:38 | 显示全部楼层
typedef struct
{
    unsigned int  task_headPosition;   
    unsigned int  task_tailPosition;   
    unsigned char task_ringBuf[BUFFER_MAX];        
} task_ringBuffer_t;

把unsigned char task_ringBuf[BUFFER_MAX]; 改成unsigned char* ptask_ringBuff,然后不同长度的数组单独定义
回复

使用道具 举报

19

主题

150

回帖

207

积分

高级会员

积分
207
发表于 2020-4-14 17:52:52 | 显示全部楼层
知识贴。结构变量的大小。
回复

使用道具 举报

36

主题

249

回帖

357

积分

高级会员

积分
357
发表于 2020-9-17 14:51:56 | 显示全部楼层
看到的太晚了        我之前好像看到过帖子 说结构体 先定义长的  再定义短的      会省内存         扒了一下map 差不多呀   是不是我试验的方法不对?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
105942
QQ
 楼主| 发表于 2020-9-17 16:33:58 | 显示全部楼层
zhengwending 发表于 2020-9-17 14:51
看到的太晚了        我之前好像看到过帖子 说结构体 先定义长的  再定义短的      会省内存         扒了 ...

以编译器实际生成的为准。
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-3-29 17:03 , Processed in 0.215137 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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