-
2020-10-10 21:11:36
- 自身对齐值:数据类型本身的对齐值,即数据类似所占的字节数(char为1,short为2,int为4,long为8,double为8,float为4)。
- 指定对齐值:一般32位机器的指定对齐值为4。
- 有效对齐值:自身对齐值和指定对齐值中比较小的一个。
结构体对齐规则
- 对于结构体和类,要将其补齐为其有效对齐值的整数倍。
- 结构体中存放的成员的起始地址必须是其本身有效对齐值的倍数。
- 结构体也有对齐值,结构体的有效对齐值是其最大数据成员的自身对齐值。
https://www.cnblogs.com/heart-flying/p/9556401.html
更多相关内容 -
结构体字节对齐规则
2018-01-29 11:17:59结构体字节对齐规则,主要是介绍结构体字节对齐规则,内容有点长,但是很全面. -
C - 结构体字节对齐问题
2020-07-17 14:06:12关于C语言中的结构体字节对齐问题,在《C与指针》一书中提到,但是似乎没有说清楚,还是我理解不完全?所以,根据书上和网上资料,总结一些关于C语言中的结构体字节对齐的知识。这里的讨论和代码,都在VS2010下,GCC... -
c语言结构体字节对齐规则
2021-11-19 18:24:17结构体大小 struct Node { char cha; int a; char chb; }; int main() { struct Node nd = {'a',100,'b'}; int size1 = sizeof(nd); int size2 = sizeof(struct Node); int size3 = sizeof nd; printf("%d %...结构体大小
struct Node { char cha; int a; char chb; }; int main() { struct Node nd = {'a',100,'b'}; int size1 = sizeof(nd); int size2 = sizeof(struct Node); int size3 = sizeof nd; printf("%d %d %d \n",size1,size2,size3); return 0; }
由于存储变量地址对齐的问题,计算结构体大小有如下3条规则:
1、结构体变量的首地址,必须是结构体变量中的“最大基本数据类型成员所占字节数的整数倍”。
2、结构体变量中的每个成员相对于结构体首地址的偏移量,都是该成员基本数据类型所占字节数的整数倍。
3、结构体变量的总大小,为结构体变量中“最大基本数据类型成员所占字节数”的整数倍。
假设从0地址开始,a:1字节 ,然后偏移到4的时候才能存储100:4字节,
现在到达8位置,b:1字节,为了满足总大小必须是最大基本数据类型的整数倍,还要偏移3,最终为:12字节。
8字节struct node { char ch[3]; int ia; };
24字节
struct node { char cha double da; char chb; };
结构体的嵌套:struct sdate { int year; int month; int day; }; struct Student { char s_id[10]; char s_name[8]; struct sdate birthday; double grade; };
为什么要进行字节对齐呢?
1、内存大小的基本单位是字节,cpu并不是逐字节读写内存,而是以2,4,8的倍数的字节块来读写内存,所以会对基本数据类型的地址做出一些限制,他的地址必须是2,4,8的倍数,因此各种数据类型就要按一定的规则在空间上排列。
2、某些平台每次读都是从偶地址开始,如果一个int型(32位系统)如果存放在 偶地址开始的地方,那么读一个周期就能读出32bit,如果存放在奇地址开始的地方,就需要2个周期,并要对两次读出的结果的高低字节进行拼凑才能得到32bit数据,读取效率下降。
3、由于不同平台对齐方式不同,同样的结构在不同平台大小可能不同,如果互发数据可能错乱,引发严重的问题。
指定对齐值
预处理指令#pragma pack(n) n取值是1,2,4,8,16
vs:8 gcc : 4#pragma pack(1) struct Node { char cha; int a; char chb; }; int main() { struct Node nd = {'a',100,'b'}; int size1 = sizeof(nd); int size2 = sizeof(struct Node); int size3 = sizeof nd; printf("%d %d %d \n",size1,size2,size3); return 0; }
1、结构体变量的首地址,必须是min(“结构体变量最大基本数据类型成员所占字节数”,指定对齐方式(比较,取小值))整数倍”。
2、结构体变量中的每个成员相对于结构体首地址的偏移量,都是min(基本数据类型成员,指定对齐方式(比较))大小的整数倍。
3、结构体变量的总大小,为(min)结构体变量中“最大基本数据类型成员所占字节数”(将嵌套结构体里的基本数据类型也算上,得到最大基本数据类型成员所占字节数)与指定对齐大小比较,取小的)大小的整数倍。由于结构体所占空间与内部元素的类型有关,而且与不同类型元素的排列顺序有关。
-
C语言结构体字节对齐规则
2019-04-12 10:55:40C语言结构体字节对齐规则 基本规则 规则1 :结构体(struct)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存放在offset为该数据成员大小的整数倍的地方(比如int在32位机为4字节,则要从4的...C语言结构体字节对齐规则
基本规则
规则1
:结构体(struct)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存放在offset为该数据成员大小的整数倍的地方(比如int在32位机为4字节,则要从4的整数倍地址开始存储)。规则2
:如果一个结构体B里嵌套另一个结构体A,则结构体A应从offset为A内部最大成员的整数倍的地方开始存储。(struct B里存有struct A,A里有char,int,double等成员,那A应该从8的整数倍开始存储。),结构体A中的成员的对齐规则仍满足原则1、原则2。Tips:
- 结构体A所占的大小为该结构体成员内部最大元素的整数倍,不足补齐。
- 不是直接将结构体A的成员直接移动到结构体B中
规则3
:结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍,不足的要补齐。案例解析
例1
typedef struct A{ int a; short b; }A; /** * 内存对齐规则: * 按最长的类型的长度为最长长度 * 4*0 = 0 所以从 0 位置开始放 * 2*0 = 0 0位置已经有内容 * 2*1 = 2 2位置已经有内容 * 2*2 = 4 4位置空,可以存放 * short长度 为2 而基准长度为4,因此 需要将剩余的两字节补空 * 故 A大小为8字节 * a a a a * b b - - */ printf("%d\n",sizeof(A));//8
例2
typedef struct B{ double a; short b; int c; }B; /** * 最长基准长度为8 * 8*0 = 0 放于0位置起的8个字节 * 2*0 = 0 此处有内容 * ... * 2*4 = 8 此处空闲可以存放 8-10用于存放 short * 4*0 = 0 此处已经有内容 * ... * 4*3 = 12 此处可以存放 12-15 * a a a a a a a a * b b - - c c c c * 所以B共占用 16字节 */ printf("%d\n",sizeof(B));
例3
typedef struct C{ short a; double b; int c; }C; /** * 最长基准长度为:8 * 2*0 = 0 0-1位置用于存放a * 8*0 = 0 此处已有内容 * 8*1 = 8 8-16位置用于存放b * 4*0 = 0 此处已有内容 * 4*3 = 12 12-16存放c * a a - - - - - - * b b b b b b b b * c c c c - - - - */ printf("%d\n",sizeof(C)); //24
例4
typedef struct D{ int a; double b; }D; typedef struct E{ short a; int b; D c; }E; /** * 当结构体内部嵌套结构体时,以两个结构体内部最长的类型为基准长度 * 此处结构体D与E最长的长度为D中的double,因此基准长度为:8 * 2 * 0 = 0 0-1位置存放E.a * 4 * 0 = 0 * 4 * 1 = 4 4-7位置存放E.b * 8 + 4 * 0 = 8 8-11位置存放D.a * 8 + 8 * 0 = 8 * 8 + 8 * 1 = 16 16-23位置存放D.b */ printf("%d\n",sizeof(E)); //24
-
C 结构体字节对齐规则
2018-01-29 11:10:32文档下载:结构体字节对齐规则 原则1:数据成员的对齐规则(以最大的类型字节为单位)。 结构体(struct)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存放在offset为该数据成员大小的整数倍的...文档下载:结构体字节对齐规则
原则1:数据成员的对齐规则(以最大的类型字节为单位)。
结构体(struct)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存放在offset为该数据成员大小的整数倍的地方(比如int在32位机为4字节,则要从4的整数倍地址开始存储)
原则2:结构体作为成员的对齐规则。
如果一个结构体B里嵌套另一个结构体A,则结构体A应从offset为A内部最大成员的整数倍的地方开始存储。(struct B里存有struct A,A里有char,int,double等成员,那A应该从8的整数倍开始存储。),结构体A中的成员的对齐规则仍满足原则1、原则2。
注意:
1. 结构体A所占的大小为该结构体成员内部最大元素的整数倍,不足补齐。
2. 不是直接将结构体A的成员直接移动到结构体B中
原则3:收尾工作
结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍,不足的要补齐。
///1
struct
{
int a;
short b;
}A;
//对齐单位为 4 个字节
//偏移量:
a: 4*0 = 0
b: 2*2 = 4
sizeof(A) = 8;
/2
struct
{
int a;
char b;
short c;
}A;
//对齐单位 4 个字节
sizeof(A) = 8;
a: 4*0 = 0
b: 1*4 = 4
c: 2*3 = 6
/3
struct
{
char b;
int a;
short c;
}A;
sizeof(A) = 12;
b: 1*0 = 0
a: 4*1 = 4
c: 2*4 = 8
/4
struct A
{
int a;
doubleb;
float c;
};
struct
{
chare[2];
int f;
doubleg;
short h;
struct Ai;
}B;
//对齐单位 8 个字节
sizeof(B) = 48;
//普通成员偏移量
e: 1*0 = 0
f: 4*1 = 4
g: 8*1 = 8
h: 2*8 = 16
结构体起点坐标:
8*3 = 24
//结构体成员偏移量
a: 24 + 4*0 = 24
b: 24 + 8*1 = 32
c: 24 + 4*4 = 40
/6
struct A
{
int a;
doubleb;
float c;
};
struct
{
chare[2];
int f;
Int g;
short h;
struct Ai;
}B;
//对齐单位 8 个字节
sizeof(B) = 40
//普通成员偏移量
e: 2*0 = 0
f: 4*1 = 4
g: 4*2 = 8
h: 2*6 = 12
结构体起点坐标:
8*2 = 16
//结构体成员偏移量
a: 16 + 4*0 = 16
b: 16 + 8*1 = 24
c: 16 + 4*4 = 32
/6
struct A
{
char e;
short f;
};
struct
{
int a;
char b;
struct Ac;
char d;
}B;
sizeof(B) = 12;
a: 4*0 = 0;
b: 1*4 = 4;
结构体起点坐标:
2*3 = 6
e: 6+1*0 = 6
f: 6+2*1 = 8
d: 1*10 = 10
/7
struct A
{
int e;
short f;
};
struct
{
int a;
char b;
struct Ac;
short d;
}B;
sizeof(B) = 20;
a: 4*0 = 0
b: 1*4 = 4
结构体起点:
4*2 = 8
e: 8 + 4*0 = 8
f: 8 + 2*2 = 12 //结构体A所占的大小为该结构体成员内部最大元素的整数倍,不足补齐。
d: 2*8 = 16
/8
#pragma pack(2) //指定对齐单位为2个字节
typedef struct
{
int a;
char b;
short c;
char d;
}A;
a: 2*0 = 0
b: 1*4 = 4
c: 2*3 = 6
d: 1*8 = 8
sizeof(A) = 10;
#pragma pack(2)
typedef struct
{
char a;
char b;
short c;
int d;
}A;
a: 1*0 = 0
b: 1*1 = 1
c: 2*1 = 2
d: 2*2 = 4
sizeof(A) = 8;
#pragma pack(1)
typedef struct
{
int d;
char a;
short c;
char b;
}A;
sizeof(A) = 8
//有关不完整类型的字节对齐
使用位域的主要目的是压缩存储,其大致规则为:
1) 一个位域必须存储在同一个字节中,不能跨两个字节。如一个字节所剩空间不够存放另一位域时,应从下一单元起存放该位域。
2) 如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止;
3) 如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍;
4) 如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6采取不压缩方式,Dev-C++和gcc采取压缩方式;
5) 如果位域字段之间穿插着非位域字段,则不进行压缩;
6) 整个结构体的总大小为最宽基本类型成员大小的整数倍。
//以 4 字节对齐
struct A
{
int a1:5;
int a2:9;
char c;
int b:4;
short s;
}B;
sizeof(B) = 16
a1 + a2 = 14 位,少于32位,4字节
a1+a2存放在一起:4*0 = 0
c: 1 * 4 = 4
b: 4 * 2 = 8 //所占的大小为该结构体成员内部最大元素的整数倍(4对齐),不足补齐。
s: 2 * 6 = 12
#pragma pack(2) //2字节对齐
struct A
{
int a1 : 5;
int a2 : 9;
char c;
int b : 4;
short s;
}B;
sizeof(B) = 12;
a1+a2 = 14 (小于32位,4字节)
a1+a2: 2 * 0 =0;
c: 1 * 4 = 4;
b: 2 * 3 =6; //4超过2字节,以2字节为单位
s:2 * 5 = 10
struct A
{
int a : 5;
int b : 7;
int c : 6;
int d : 9;
char e : 2;
int x;
}B;
sizeof(B) = 12
a+b+c+d = 27 < 32
a+b+c+d放在一起: 4 * 0 = 0
e : 1 * 4 = 4
x: 4 * 2 = 8
-
C++ 结构体字节对齐规则
2022-05-17 15:25:09对齐有两个规则 一、不但结构体的成员有有效对齐值,结构体自己也有对齐值,这主要是考虑结构体的数组,对于结构体或者类,要将其补齐为其有效对齐值的整数倍。结构体的有效对齐值是其最大数据成员的自身对齐值; ... -
C/C++结构体字节对齐详解
2020-12-22 23:51:15我们先看看sizeof的定义——sizeof的结果等于对象或者类型所占的内存字节数,好吧,那让我们来看看S1的内存分配情况 S1 s1 = { 'a', 0xFFFFFFFF }; 定义上面的变量后,加上断点,运行程序,观察s1所在的... -
c语言结构体字节对齐详解
2021-05-19 10:53:411.什么是字节对齐在c语言的结构体里面一般会按照某种规则去进行字节对齐。我们先看一段代码:struct st1{char name;double age;char sex;};//32位下 sizeof(struct st1) = 16//64位下 sizeof(struct st1) = 24struct... -
结构体字节对齐
2020-03-31 21:27:39结构体字节对齐 字节对齐的作用和原因: 各个硬件平台对存储空间的处理上有很大的不同。一些平台对某些特定类型的数据只能从某些特定地址开始存取。比如有些架构的CPU在访问一个没有进行对齐的变量的时候会发生错误... -
结构体字节对齐问题
2021-04-14 14:28:14文章目录一、结构体必知知识二、结构体字节对齐有什么用?三、如何进行内存对齐?1.对齐规则:按结构体中最长类型字节为单位2.结构体嵌套的情况3.存在指定字节对齐单位的情况(#pragma pack)总结 一、结构体必知知识... -
struct结构体字节对齐原则及为什么要对齐?
2019-01-06 11:30:21http://blog.sina.com.cn/s/blog_14ecf1a5b0102x27j.html ... //-------------------------------------------------------- 本文目录结构 |-为什么结构体内存对齐 |-结构体内... -
结构体字节对齐 c语言结构体字节对齐详解
2019-08-16 17:46:32这就牵扯到结构体中字节对齐的概念。 (什么叫字节对齐?结构体是一种构造数据类型,里面可以有不同的数据类型的成员,在这些数据成员中,不同的数据类型所占的内存空间是不同的,那么这些成员是... -
C语言-结构体 字节对齐
2022-05-08 13:41:03由于结构体存在字节对齐,所以结构体所占字节大小不是其各成员所占字节数之和!! 例1:下面程序结果为12,不是6! #include<stdio.h> struct Node { char cha; int ia; char chb; }; int main() { ... -
struct结构体字节对齐
2021-05-16 02:43:10//--------------------------------------------------------本文目录结构|-为什么结构体内存对齐|-结构体内存对齐规则|-具体举例//--------------------------------------------------------一、为什么结构体内存... -
结构体对齐(字节对齐)规则及大小计算
2020-07-15 20:30:01什么是字节对齐 这跟读取数据有关,cpu读取一次能读取到的内存大小跟数据总线的位数有关,如果数据总线为16位,那么cpu一次能够读取2字节;如果为32位那么cpu一次可以读取4字节,而读取数据是需要消耗时间的,为了... -
结构体字节对齐之嵌套结构体
2020-03-21 16:47:22根据结构体对齐规则可知,Demo的大小: #pragma pack(1) class Demo { short int a;//2字节【规则1偏移量为0】 char ss[3];//3字节【规则1偏移量为2,是min(1,1)=1的整数倍】 }; //【规则2:总大小5字节,是min(1... -
C 结构体字节对齐的方法
2020-11-05 17:03:36字节对齐在通讯协议解析中用起来相当方便,这里记录下C结构体字节对齐的几种方法: 方法1: #pragma pack(1) //包含你所需要的结构体 #pragma pack() 方法2: attribute ((packed))修饰你所需要的结构体 typedef ... -
c# 结构体 4字节对齐_结构体的字节对齐
2020-11-21 00:09:45先说结论:sizeof求得的结构体的大小并不一定等于各个数据成员的大小之和。...而结构体A和B使用sizeof的结果分别为16个字节和24个字节。可以看出结构体B所占的字节数并不等于其成员之和:sizeof(B) ≠ sizeo... -
设置结构体字节对齐
2019-12-18 22:27:48结构对齐 按照一字节对齐(默认的为四字节对齐,并且要为最大类型的整数倍) #pragma pack(push,1) 结构体的定义 #pragma pack(pop) -
结构体字节对齐详解【含实例】
2021-10-16 14:47:09结构体字节对齐属于老生常谈的问题,看似简单,但却很容易忘记。而且因为结构体使用的普遍性,使得字节对齐也成为了一个不得不谈的话题。之前在C语言作业中有相应的题目,总结了一番,写下了这篇博客。最近抽出时间... -
由笔试题引发的结构体字节对齐规则总结
2021-03-07 10:55:18很多网上的字节对齐规则是这样: 1.结构体变量的首地址为最宽基本类型成员大小的整数倍数。 2.各成员变量存放的起始地址相对于结构体变量的起始地址的偏移量必须为该变量类型所占用的字节数的倍数 3.结构体总大小... -
c# 结构体 4字节对齐_零基础入门之结构体字节对齐
2020-11-21 00:09:42一、字节对齐的规则: 1、一般设置的对齐方式为1,2,4字节对齐方式。结构的首地址必须是结构内最宽类型的整数倍地址;另外,结构体的每一个成员起始地址必须是自身类型大小的整数倍(需要特别注意的是windows下是...