C语言中的字节对齐
下面这个篇博客讲解很好
http://blog.csdn.net/meegomeego/article/details/9393783
总的来看分三类:
1. 不加 #pragma pack(n)伪指令(n未对齐的字节数目)
2. 加#pragma pack(n) 伪指令
3. __attribute__((aligned(n)))来使用n个字节方式的对齐
第一种:不加 #pragma pack(n)伪指令
对其的字节数目为一个结构体中的基本类型(int char float double,特别强调复合型(数组、结构体、联合体)不算。)成员变量中最大的字节数(也可理解为默认对齐字节数,如char 默认 1字节 int 默认 4字节 等)。
第二种:加#pragma pack(n) 伪指令
对其的字节数目为一个结构体中的基本类型(int char float double,特别强调复合型(数组、结构体、联合体)不算。)成员变量最大的字节数(也可理解为默认对齐字节数,如char 默认 1字节 int 默认 4字节 等) 与pragma pack(n) 中的n值二者之间的较小数为对齐的字节数。比如:一个结构体中基本类型的
成员变量为 float a;//默认是4字节对齐,而加#pragma pack(8) 设置为8字节,此时加#pragma pack(8)设置失效,是4字节对齐(4 < 8),如果 n 为 2,那么对齐的字节数就是2字节了(2 < 4)。
经典例子:
1 // 例3(如果在GCC中编译,请加上-malign-double选项)
2 #pragma pack(8)
3 struct s1
4 {
5 short a; // 第一个成员,放在[0, 1]偏移的位置。
6 long b; // 第二个成员sizeof(long)=4, #pragma pack(8), 取小值也就是4
7 // 所以这个成员按4字节对齐,放在偏移[4~7]的位置。
8 };
9 // struct s1中size最大的数据成员(4), #pragma pack(8)
10 // 取小值也就是4,所以sizeof(struct s1)应当按照4来对齐,为8
11
12 struct s2
13 {
14 char c; // 第一个成员,放在[0]偏移的位置。
15 struct s1 d; // 第二个成员为struct s1,其对齐方式是它的所有成员使用的对齐参数中最大的一个,即4。
16 // 所以第二个成员d按4字节对齐,由于sizeof(d)=8, 放在偏移[4~11]的位置。
17 long long e; // 第三个成员sizeof(long long)=8, #pragma pack(8), 取小值也就是8
18 // 所以这个成员按8字节对齐,放在偏移[16~23]的位置。
19 };
20 #pragma pack()
第三种:__attribute__((aligned(n)))来使用n个字节方式的对齐
这种方式和第二种的方式是刚好相反的,取得是较大值来作为字节对齐。
经典例子:
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 #pragma pack(16)
5 struct testa
6 {
7 unsigned int number;
8 };
9 #pragma pack()
10 struct testa arr_testa[4] = { {65535}, {65535}, {65535}, {65535} };
11
12 struct testb
13 {
14 unsigned int number;
15 } __attribute__ ((aligned (16))) ;
16
17 struct testb arr_testb[4] = { {65535}, {65535}, {65535}, {65535} };
18
19
20 int main(int argc, const char *argv[])
21 {
22 printf("sizeof(struct testa) = %d, sizeof(arr_testa) = %d\n",
23 sizeof(struct testa), sizeof(arr_testa));
24 printf("sizeof(struct testb) = %d, sizeof(arr_testb) = %d\n",
25 sizeof(struct testb), sizeof(arr_testb));
26
27 printf("address of arr_testa[0] = %p\n", &arr_testa[0]);
28 printf("address of arr_testa[1] = %p\n", &arr_testa[1]);
29 printf("address of arr_testa[2] = %p\n", &arr_testa[2]);
30 printf("address of arr_testa[3] = %p\n", &arr_testa[3]);
31 puts("");
32 printf("address of arr_testb[0] = %p\n", &arr_testb[0]);
33 printf("address of arr_testb[1] = %p\n", &arr_testb[1]);
34 printf("address of arr_testb[2] = %p\n", &arr_testb[2]);
35 printf("address of arr_testb[3] = %p\n", &arr_testb[3]);
36 return 0;
37 }
输出结果为:
1 sizeof(struct testa) = 4, sizeof(arr_testa) = 16
2 sizeof(struct testb) = 16, sizeof(arr_testb) = 64
3 address of arr_testa[0] = 0x804a040
4 address of arr_testa[1] = 0x804a044
5 address of arr_testa[2] = 0x804a048
6 address of arr_testa[3] = 0x804a04c
7
8 address of arr_testb[0] = 0x804a060
9 address of arr_testb[1] = 0x804a070
10 address of arr_testb[2] = 0x804a080
11 address of arr_testb[3] = 0x804a090
特别强调注意union 的字节对齐:
1 union AAA{
2 double i;//8B
3 int k[5];//20B
4 cahr b; //1B
5 }
上面的unionAAA类型,类型的字节大小为sizeof(AAA) ,按固有的原则来看,应该取AAA中长度最长的成员的程度。但是容易忽略一点就是字节对齐问题。综合考虑union类型的字节大小的求解,从如下两方面入手:
1. 找到占内长度最大的成员
2. 考虑字节对齐问题
union AAA:
1. k[5] 占内存20字节最大
2. 最长的基本类型成员为double类型,占据8字节。故最后union AAA占用内存应该是8的倍数,20 + 4 即可。
sizeof(AAA) = 24字节!
C语言中的字节对齐的更多相关文章
- C语言中的字节对齐以及其相关处理
首先,我们来了解下一些基本原理: 一.什么是字节对齐一个基本类型的变量在内存中占用n个字节,则该变量的起始地址必须能够被n整除,即: 存放起始地址 % n = 0,那么,就成该变量是字节对齐的;对于结 ...
- C语言中结构体对齐问题
C语言中结构体对齐问题 收藏 关于C语言中的结构体对齐问题 1,比如: struct{short a1;short a2;short a3;}A;struct{long a1;short a2;}B; ...
- C语言中的内存对齐
最近看了好多,也编了好多C语言的浩强哥书后的题,总觉的很不爽,真的真的好怀念linux驱动的代码,好怀念那下划线,那结构体,虽然自己还很菜. 同时看了一遍陈正冲老师的C语言深度剖析,收益很多,又把唐老 ...
- C语言:内存字节对齐详解[转载]
一.什么是对齐,以及为什么要对齐: 1. 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问, ...
- C语言:内存字节对齐详解
转:http://blog.csdn.net/arethe/article/details/2548867 一.什么是对齐,以及为什么要对齐: 1. 现代计算机中内存空间都是按照byte划分的,从理论 ...
- ACE的CDR中的字节对齐问题
大家应该都知道计算机中间都有字节对齐问题.CPU访问内存的时候,如果从特定的地址开始访问一般可以加快速度,比如在32位机器上,如果一个32位的整数被放在能被32模除等于0的地址上,只需要访问一次,而如 ...
- c语言,内存字节对齐
引用:内存字节对齐 写出一个struct,然后sizeof,你会不会经常对结果感到奇怪?sizeof的结果往往都比你声明的变量总长度要大,这是怎么回事呢?讲讲字节对齐吧. /************* ...
- C++中的字节对齐分析
struct A { int a; char b; short c; }; struct B { char a; int b; short c; }; #pragma pack(2) struct C ...
- [置顶]
什么是C语言结构体字节对齐,为什么要对齐?
一.概念 对齐跟数据在内存中的位置有关.如果一个变量的内存地址正好位于它长度的整数倍,他就被称做自然对齐.比如在32位cpu下,假设一个整型变量的地址为0x00000004,那它就是自然对齐的. ...
随机推荐
- C语言中都有哪些常见的数据结构你都知道几个??
上次在面试时被面试官问到学了哪些数据结构,那时简单答了栈.队列/(ㄒoㄒ)/~~其它就都想不起来了,今天有空整理了一下几种常见的数据结构,原来我们学过的数据结构有这么多~ 首先,先来回顾下C语言中常见 ...
- 个人宽带如何开启IPv6网络访问
IPv6是大势所趋,就在前段时间湖南联通发布公告,对家庭宽带提供 IPv6 地址,不再提供 IPv4地址,那本文就介绍 个人宽带如何开启 IPv6网络访问. 湖南联通停止向普通家庭宽带用户提供公网 I ...
- 从零开始的DIY智能家居 - 基于 ESP32 的土壤湿度传感器
前言 自从上次做了那个 甲醛传感器 和 水浊度传感器 之后开始尝到智能家居的甜头了,这两东西有没有用我不知道,但是没事的时候掏出手机瞄两眼,看着就让人很安心( ̄︶ ̄). 于是懒惰的我开始琢磨把给植物浇 ...
- LOTO实践【干货】电压比较器的快速应用
LOTO实践[干货]电压比较器的快速应用 话不多说先上图: 最近出差去客户那边做设备调试,现场如上图,其中我负责的技术部分包含了一个掉落物监测的功能.硬件上的原理比较简单,发射板上的红外发射头阵列,以 ...
- 一文读懂什么是渲染管线(7k字)
01 | 渲染基础 渲染(Render)定义 渲染在电脑绘图中是指软件从模型生成图像的过程,通俗讲就是在计算机里面给虚拟世界"拍照".渲染主要分为两种,一种是预渲染(pre-ren ...
- GitHub上 README 增加图片标签
hey Guys~ 你可能遇到的GitHub上好的项目都有一个非常棒的README,其中不乏用到一些非常好看的标签.比如下面这样: walle fastjson 那我们怎样自己添加一个高大上图片标签呢 ...
- ASP.NET Core设置URLs的几种方法
前言 在使用ASP.NET Core 3.1开发时,需要配置服务器监听的端口和协议,官方帮助文档进行简单说明,文档中提到了4种指定URL的方法 设置ASPNETCORE_URLS 环境变量: 使用do ...
- SQL告警,执行时间长?教你写一手好 SQL !
博主(编码砖家)负责的项目主要采用阿里云数据库MySQL,最近频繁出现慢SQL告警,执行时间最长的竟然高达5分钟.导出日志后分析,主要原因竟然是没有命中索引和没有分页处理 . 其实这是非常低级的错误, ...
- lombok标签之@Data @AllArgsConstructor @@NoArgsConstructor -如何去除get,set方法。@Data注解和如何使用,lombok
在代码中我们可以只加上标签@Data 而不用get,set方法: val : 和 scala 中 val 同名, 可以在运行时确定类型; @NonNull : 注解在参数上, 如果该类参数为 null ...
- 设计模式学习-使用go实现装饰模式
装饰器模式 定义 代码实现 优点 缺点 适用范围 装饰器模式和桥接模式的区别 参考 装饰器模式 定义 装饰模式:动态的给一些对象添加额外的职责,就增加功能来说,装饰模式比生成子类更灵活. 举个栗子: ...