C语言-字节对齐
Posted 深蓝嵌入式
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言-字节对齐相关的知识,希望对你有一定的参考价值。
什么是字节对齐
字节对齐作用
字节对齐的作用不仅是便于cpu快速访问,同时合理的利用字节对齐可以有效地节省存储空间。
对于32位机来说,4字节对齐能够使cpu访问速度提高,比如说一个long类型的变量,如果跨越了4字节边界存储,那么cpu要读取两次,这样效率就低了。但是在32位机中使用1字节或者2字节对齐,反而会使变量访问速度降低。所以这要考虑处理器类型,另外还得考虑编译器的类型。在vc中默认是4字节对齐的,GNU gcc 也是默认4字节对齐。
字节对齐的方式
1. 使用伪指令#pragma pack
使用伪指令#pragma pack (n),C编译器将按照n个字节对齐。
使用伪指令#pragma pack (),取消自定义字节对齐方式。
需要注意的是,#pragma pack
结构体对齐规则举例:
摘自:https://blog.csdn.net/lime1991/article/details/44536343
结构体中各个成员按照它们被声明的顺序在内存中顺序存储。
1)将结构体内所有数据成员的长度值相加,记为sum_a;
2)将各数据成员内存对齐,按各自对齐模数而填充的字节数累加到和sum_a上,记为sum_b。对齐模数是【该数据成员所占内存】与【#pragma pack指定的数值】中的较小者。
3)将和sum_b向结构体模数对齐,该模数是【#pragma pack指定的数值】、【未指定#pragma pack时,系统默认的对齐模数4字节】和【结构体内部最大的基本数据类型成员】长度中数值较小者。结构体的长度应该是该模数的整数倍。
3.1 基本数据类型所占内存大小
以下例子均按32bit编译器处理。
3.2 Test1
struct Test1
{
char c;
short sh;
int a;
float f;
int *p;
char *s;
double d;
};
上述结构体总共占28Bytes。
c的偏移量为0,占1个Byte。
a占4个Byte,对齐模数是4,因此接在sh后存放即可,偏移量为4。
2. 使用 __attribute__属性
__attribute((aligned (n))),让所作用的结构成员对齐在n字节自然边界上。如果结构中有成员的长度大于n,则按照最大成员的长度来对齐。
__attribute__ ((packed)),取消结构在编译过程中的优化对齐,按照实际占用字节数进行对齐。
typedef struct
{
uint8_t len;
uint8_t is_need_update;
uint8_t data[3];
uint64_t padding;
} v_keys_stg __attribute__((aligned(8)));
static v_keys_stg g_vk_data = {0};
static v_keys_stg g_vm_data = {0};
app.map文件
Symbol Name addr type size object
g_vk_data 0x00211a30 Data 16 key_handle.o(.bss)
g_vm_data 0x00211a40 Data 16 key_handle.o(.bss)
__attribute__设置的值进行对齐变化,但是实际的占用的size大小没有变化的;
以上是关于C语言-字节对齐的主要内容,如果未能解决你的问题,请参考以下文章