前言:
我们在学到c语言内存管理的时候总是一遍惊叹,其聪明的内存管理策略,一遍抱怨其难以理解的方法,网上的资料要不讲究的太详细,要不没能讲解清楚,今天我们根据实例来学习一下基于32位操作系统的的C语言:内存字节对齐
tip:在32位编译模式下,默认以4字节对齐;在64位编译模式下,默认以8字节对齐。
目录
1.?什么是对齐?
2.?计算机为什么要对齐?
?3.我们直接上代码
案例一
?案例二
对齐规律?
名词解释:
对齐有两个规则:
1.?什么是对齐?
现代计算机中内存空间都是按照字节(byte)划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问,这就需要各类型数据按照一定的规则在空间上排列,而不是顺序地一个接一个地排放,这就是对齐。
2.?计算机为什么要对齐?
各个硬件平台对存储空间的处理上有很大的不同。一些平台对某些特定类型的数据只能从某些特定地址开始存取,其他平台可能没有这种情况。但是如果不按照适合其平台的要求对数据存放进行对齐,会在存取效率上带来损失。
例如一个 int 类型的数据,如果地址为 8,那么很好办,对编号为 8 的内存寻址一次就可以。如果编号为 10,就比较麻烦,CPU需要先对编号为 8 的内存寻址,读取4个字节,得到该数据的前半部分,然后再对编号为 12 的内存寻址,读取4个字节,得到该数据的后半部分,再将这两部分拼接起来,才能取得数据的值。
将一个数据尽量放在一个步长之内,避免跨步长存储,这称为内存对齐。在32位编译模式下,默认以4字节对齐;在64位编译模式下,默认以8字节对齐。
?3.我们直接上代码
案例一
#include <stdio.h>
void main(){
struct A{
char a;
short b;
int c;
};
printf( "size of struct A = %d \n", sizeof(struct A) );
}
输出结果为:8字节。
我们来看图
第一步:
首先自身对齐值最大(也就是int型)是4? 32位操作系统的对齐值也是4,所以有效对齐值就是4
第二步:
满足存放成员的起始地址必须是该成员有效对齐值的整数倍
a是char型数据,占用1字节内存;short型数据,占用2字节内存;int型数据,占用4字节内存。因此,结构体A的自身对齐值为4。于是,a和b要组成4个字节,以便与c的4个字节对齐。而a只有1个字节,a与b之间便空了一个字节。我们知道,结构体类型数据是按顺序存储结构一个接一个向后排列的
?案例二
#include <stdio.h>
void main(){
struct A{
short b;
int c;
char a;
};
printf( "size of struct A = %d \n", sizeof(struct A) );
}
输出结果为:12字节。
我们来看图
第一步:
自身对齐值最大(也就是int型)是4? 32位操作系统的对齐值也是4,所以有效对齐值就是4
第二步:
满足存放成员的起始地址必须是该成员有效对齐值的整数倍
b是short型数据,占用2字节内存;chart型数据,占用1字节内存;int型数据,占用4字节内存。因此,结构体A的自身对齐值为4。于是,b一个数据占4字节(原本是两个字节),c一个数据占4字节,a一个数据占4字节(原本一个字节)
类比成这样子(对齐的样子)
对齐规律?
名词解释:
这里引入四个概念
数据类型自身的对齐值,
指定对齐值,
结构体或者类的自身对齐值,
数据成员、结构体和类的有效对齐值
1)数据类型自身的对齐值:就是基本数据类型的自身对齐值,比如char类型的自身对齐值为1字节,int类型的自身对齐值为4字节。
2)指定对齐值:预编译命令#pragma pack (value)指定的对齐值value。
3)结构体或者类的自身对齐值:其成员中自身对齐值最大的那个值,比如以上的struct A的对齐值为4。
4)数据成员、结构体和类的有效对齐值:自身对齐值和指定对齐值中较小的那个值。
对齐有两个规则:
1、首先?结构体的自身对齐值和操作系统的对齐值相比,取小的那个就是有效对齐值
比如下面这个?结构体的自身对齐值是4?操作系统的对齐值也是4,所以有效对齐值就是4? ?
#include <stdio.h>
void main(){
struct A{
short b;
int c;
char a;
};
printf( "size of struct A = %d \n", sizeof(struct A) );
}
2、满足存放成员的起始地址必须是该成员有效对齐值的整数倍。
通俗来说就是每一个数据类型和有效对齐值相比 ????????????????取大的那个值就是最后的有效对齐值
#include <stdio.h>
void main(){
struct A{
short b;
int c;
char a;
};
printf( "size of struct A = %d \n", sizeof(struct A) );
}
还是上面的代码,b为short型(1字节)和有效对齐值(4字节)相比取大的值就是4字节
|