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

#pragma pack(4)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 objectg_vk_data 0x00211a30 Data 16 key_handle.o(.bss)g_vm_data 0x00211a40 Data 16 key_handle.o(.bss)


__attribute__设置的值进行对齐变化,但是实际的占用的size大小没有变化的;

以上是关于C语言-字节对齐的主要内容,如果未能解决你的问题,请参考以下文章

C语言-字节对齐

C语言 大小端 字节对齐

C语言:内存字节对齐详解[转载]

C语言字节对齐分析

C语言结构体变量字节对齐问题总结

C语言字节对齐