linux内存对齐图,Linux C语言: 结构体内存对齐和补齐原理

结构体内存对齐

系统:Linux 64位CenOS 7 GCC编译器

内存对齐的表现

typedef struct {

int a; // 4 bytes

char b[5]; // 5 bytes

double c; // 8 bytes

int d; // 4 bytes

short e; // 2 bytes

}MemAlign;

Sizeof(MemAlign) = 32

单个参数计算总和为23个字节,而整个结构体却是32个字节,这是为什么呢?

为什么要进行内存对齐?

我们大多数人在没有搞清楚CPU是如何读取数据的时候,基本都会认为CPU是一字节一字节读取的,但实际上它是按照块来读取的,块的大小可以为2字节,4字节,8字节,16字节。Linux 64位下默认为8字节。

1、平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常,特别是嵌入式设备。

2、性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。

cd46894b3278432508da0b01f2078e0f.png

对齐补齐原则

有点文章给出了很复杂的解释,我总结就这两个

(1)第一个成员首地址从0开始。

(2)第一个成员内存大小必须是对齐字节数的整数倍或被整除。从第二个成员开始累加前面所有成员内存大小必须是对齐字节数的整数倍。

#include

#include

#pragma pack(8) typedef struct { int a; // 4 bytes char b[5]; // 5 bytes double c; // 8 bytes int d; // 4 bytes short e; // 2 bytes }MemAlign; typedef struct { int a; MemAlign ma; char c; } NewAlg; #pragma pack(8) int main(int argc, char argv[]) { MemAlign mA; int mlen = sizeof(MemAlign); int al = sizeof(mA.a); int bl = sizeof(mA.b); int cl = sizeof(mA.c); int dl = sizeof(mA.d); int el = sizeof(mA.e); printf("al = %d, bl = %d, cl = %d, dl = %d, el = %d, sum(%d), sizeof = %d \n", al, bl, cl, dl, el,(al+bl+cl+dl+el), mlen); printf("a=%x, b=%x,c=%x,d=%x,e=%x\n",&mA.a, &mA.b, &mA.c,&mA.d, &mA.e); memset(&mA, 0x0, mlen); memset(&mA.a, 0x1, al); memset(&mA.b, 0x2, bl); memset(&mA.c, 0x3, cl); memset(&mA.d, 0x4, dl); memset(&mA.e, 0x5, el); char *p = (char *)&mA int i; for(i = 0; i < mlen; i++) { printf("%x ", *(p+i)); } printf(" \n"); int nlen = sizeof(NewAlg); printf("nlen = %d \n", nlen); return 0; }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值