Chinaunix首页 | 论坛 | 博客
  • 博客访问: 458223
  • 博文数量: 42
  • 博客积分: 1325
  • 博客等级: 中尉
  • 技术积分: 1312
  • 用 户 组: 普通用户
  • 注册时间: 2009-01-13 18:00
个人简介

呵~~~呵~~~

文章分类

全部博文(42)

文章存档

2016年(3)

2015年(1)

2014年(2)

2013年(2)

2012年(7)

2011年(11)

2010年(3)

2009年(13)

我的朋友

分类: LINUX

2011-07-29 16:09:04

 
这篇文章是个人对内存对齐的理解,包涵示意图例.

首先,以下文字内容来源于网络资料

一、内存对齐的原因
大部分的参考资料都是如是说的:
1、平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
2、性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。

二、对齐规则
每个特定平台上的编译器都有自己的默认“对齐系数”(也叫对齐模数)。程序员可以通过预编译命令#pragma pack(n),n=1,2,4,8,16来改变这一系数,其中的n就是你要指定的“对齐系数”。

规则:
1、数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员的对齐按照#pragma pack指定的数值和这个数据成员自身长度中,比较小的那个进行。
2、结构(或联合)的整体对齐规则:在数据成员完成各自对齐之后,结构(或联合)本身也要进行对齐,对齐将按照#pragma pack指定的数值和结构(或联合)最大数据成员长度中,比较小的那个进行。
3、结合1、2颗推断:当#pragma pack的n值等于或超过所有数据成员长度的时候,这个n值的大小将不产生任何效果。

 

以下为本人理解图

以下为本人测试代码

#include "stdio.h"

struct str1
{
    char a;
    short b;
    char c;
    int d;
};

struct str2
{
    int a;
    char b;
    short c;
    char d;
    int e;
};

int main(int argc, char *argv[])
{

    struct str2 s;
    
    int al,bl,cl,dl,el;
    al = (int)&s.b - (int)&s.a;
    bl = (int)&s.c - (int)&s.b;
    cl = (int)&s.d - (int)&s.c;
    dl = (int)&s.e - (int)&s.d;
    el = sizeof(s) - (al+bl+cl+dl);

    struct str1 m;
    int ma = (int)&m.b - (int)&m.a;
    int mb = (int)&m.c - (int)&m.b;
    int mc = (int)&m.d - (int)&m.c;
    int md = sizeof(m) - (ma+mb+mc);
    
    printf( "s:%d\n", sizeof(s));
    printf( "a=%d b=%d c=%d d=%d e=%d\n", al, bl, cl, dl, el);
    
    printf( "m:%d\n", sizeof(m));
    printf( "a=%d b=%d c=%d d=%d\n", ma, mb, mc, md);
    
}


32位linux、默认对齐系数,结果如下:

DEV:/home # ./a.out
s:16
a=4 b=2 c=2 d=4 e=4
m:12
a=2 b=2 c=4 d=4

 

阅读(1633) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~