程序让生活更美好

半亩方塘 天光云影

  C++博客 ::  :: 新随笔 :: 联系 ::  :: 管理 ::
  55 随笔 :: 4 文章 :: 202 评论 :: 0 Trackbacks

内存对齐

         在我们的程序中,数据结构还有变量等等都需要占有内存,在很多系统中,它都要求内存分配的时候要对齐,这样做的好处就是可以提高访问内存的速度。


 我们还是先来看一段简单的程序:


                                程序一

 1 #include <iostream>
 2 using namespace std;
 3 
 4 struct X1
 5 {
 6   int i;//4个字节
 7   char c1;//1个字节
 8   char c2;//1个字节
 9 };
10 
11 struct X2
12 {
13   char c1;//1个字节
14   int i;//4个字节
15   char c2;//1个字节
16 };
17 
18 struct X3
19 {
20   char c1;//1个字节
21   char c2;//1个字节
22   int i;//4个字节
23 };
24 int main()
25 {   
26     cout<<"long "<<sizeof(long)<<"\n";
27     cout<<"float "<<sizeof(float)<<"\n";
28     cout<<"int "<<sizeof(int)<<"\n";
29     cout<<"char "<<sizeof(char)<<"\n";
30 
31     X1 x1;
32     X2 x2;
33     X3 x3;
34     cout<<"x1 的大小 "<<sizeof(x1)<<"\n";
35     cout<<"x2 的大小 "<<sizeof(x2)<<"\n";
36     cout<<"x3 的大小 "<<sizeof(x3)<<"\n";
37     return 0;
38 }

      
      这段程序的功能很简单,就是定义了三个结构X1,X2,X3,这三个结构的主要区别就是内存数据摆放的顺序,其他都是一样的,另外程序输入了几种基本类型所占用的字节数,以及我们这里的三个结构所占用的字节数。

这段程序的运行结果为:

1 long 4
2 float 4
3 int 4
4 char 1
5 x1 的大小 8
6 x2 的大小 12
7 x3 的大小 8


     结果的前面四行没有什么问题,但是我们在最后三行就可以看到三个结构占用的空间大小不一样,造成这个原因就是内部数据的摆放顺序,怎么会这样呢?

    下面就是我们需要讲的内存对齐了。

    内存是一个连续的块,我们可以用下面的图来表示,  它是以4个字节对一个对齐单位的:

                                                    图一

mem1.jpg

   让我们看看三个结构在内存中的布局:

   首先是 X1,如下图所示

mem2.jpg


    X1 中第一个是 Int类型,它占有4字节,所以前面4格就是满了,然后第二个是char类型,这中类型只占一个字节,所以它占有了第二个4字节组块中的第一格,第三个也是char类型,所以它也占用一个字节,它就排在了第二个组块的第二格,因为它们加在一起大小也不超过一个块,所以他们三个变量在内存中的结构就是这样的,因为有内存分块对齐,所以最后出来的结果是8,而不是6,因为后面两个格子其实也算是被用了。

    再次看看X2,如图所示

mem4.jpg

    X2中第一个类型是Char类型,它占用一个字节,所以它首先排在第一组块的第一个格子里面,第二个是Int类型,它占用4个字节,第一组块已经用掉一格,还剩3格,肯定是无法放下第二Int类型的,因为要考虑到对齐,所以不得不把它放到第二个组块,第三个类型是Char类型,跟第一个类似。所因为有内存分块对齐,我们的内存就不是8个格子了,而是12个了。


再看看X3,如下图所示:



mem3.jpg

   关于X3的说明其实跟X1是类似的,只不过它把两个1个字节的放到了前面,相信看了前面两种情况的说明这里也是很容易理解的。


   唉,写到这手都累了,关键是要画图,希望通过此文能让你理解内存对齐的基本概念,如果有问题,请留言。

此文完

posted on 2006-08-01 16:51 北风之神007 阅读(18265) 评论(31)  编辑 收藏 引用 所属分类: c/c++

评论

# re: 内存对齐 2006-08-04 16:15 xgbing
辛苦了!  回复  更多评论
  

# re: 内存对齐 2006-10-26 21:32 柯南
太好了  回复  更多评论
  

# re: 内存对齐 2007-04-11 08:19 帅哥
辛苦了,  回复  更多评论
  

# re: C++中的内存对齐 2007-09-17 15:10 mutedog@gmail.com
概念都懂,要谈一些编程中实际遇到的问题,怎么解决.因为结构的指针是一个很方便的东西,大家经常用他来对一个数据块(连续字节构成的,没有空洞的)进行格式化(map),以对各个变量进行访问.  回复  更多评论
  

# re: C++中的内存对齐 2007-09-28 17:18 clarencejaung
好, 楼主辛苦了!  回复  更多评论
  

# re: C++中的内存对齐 2007-11-09 14:12 lhl
辛苦了
学习
  回复  更多评论
  

# re: C++中的内存对齐 2007-12-22 12:59 FongLuo
简单问题,看看VC或BCB的结果声明的最前面。
使用以下语句将结构声明包起来就行了。

#pragma pack(push,1)

#pragma pop()
  回复  更多评论
  

# re: C++中的内存对齐[未登录] 2007-12-22 21:58 TheAnswer
各成员变量存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数。各成员变量在存放的时候根据在结构中出现的顺序依次申请空间,同时按照上面的对齐方式调整位置,空缺的字节自动填充。同时为了确保结构的大小为结构的字节边界数(即该结构中占用最大空间的类型所占用的字节数)的倍数,所以在为最后一个成员变量申请空间后,还会根据需要自动填充空缺的字节。

这样不是已经很清楚了吗,不用写这么长吧。  回复  更多评论
  

# re: C++中的内存对齐 2008-04-06 14:11 lunarfan
很好  回复  更多评论
  

# re: C++中的内存对齐 2008-05-02 10:53 Water
非常清晰,明白了本来不明白的东西。也感谢TheAnswer的总结  回复  更多评论
  

# re: C++中的内存对齐 2008-09-11 20:39
谢谢!!!  回复  更多评论
  

# re: C++中的内存对齐[未登录] 2008-11-05 10:55 student
看了之后,很有启发。谢谢!!!  回复  更多评论
  

# re: C++中的内存对齐 2008-12-12 09:14 chin
谢谢,这样画出来比较清晰,谢谢楼主  回复  更多评论
  

# re: C++中的内存对齐 2009-06-13 16:19 rs
真是太谢谢了 光看别人说什么好多好多
还不如这三个画呢
下面再理解那几个命令关键字 就没什么问题了 太谢谢了

  回复  更多评论
  

# re: C++中的内存对齐 2009-08-31 09:20 a heng
图画得很好,看懂了。谢谢!  回复  更多评论
  

# re: C++中的内存对齐 2009-09-01 22:47 colorrain

搂主所说好像不够全面 ,按照4字节对齐
struct
{
int a;
char b;
short c;
char d;
}
该为12
同意 TheAnswer
各成员变量存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数。各成员变量在存放的时候根据在结构中出现的顺序依次申请空间,同时按照上面的对齐方式调整位置,空缺的字节自动填充。同时为了确保结构的大小为结构的字节边界数(即该结构中占用最大空间的类型所占用的字节数)的倍数,所以在为最后一个成员变量申请空间后,还会根据需要自动填充空缺的字节。
  回复  更多评论
  

# re: C++中的内存对齐 2011-08-04 15:17 zx
感谢,终于明白原因了。  回复  更多评论
  

# re: C++中的内存对齐 2011-08-28 13:58 刺客
VC给的结果是8.@colorrain
  回复  更多评论
  

# re: C++中的内存对齐 2011-08-28 14:07 刺客
@colorrain
  回复  更多评论
  

# re: C++中的内存对齐 2011-08-28 14:07 刺客
不好意思,忘记了程序加了一句
#pragma pack(1)

去掉后默认的就是12了。。还是theAnswer说的对。
@colorrain
  回复  更多评论
  

# re: C++中的内存对齐 2012-04-06 20:57 linrulei
楼主辛苦了,但是讲解的不够清晰。个人觉得这篇文章更加详细http://www.cppblog.com/snailcong/archive/2009/03/16/76705.html  回复  更多评论
  

# re: C++中的内存对齐 2013-04-03 12:02 jiangheng
楼主辛苦,多谢!  回复  更多评论
  

# re: C++中的内存对齐 2013-11-07 15:23 牛在蓝天
还是感觉不够全:

struct A{
int a;
double b;
}

这种情况, 在window 下是 16;win下是以最长字节数补齐的,
在Unix 下则是12,Unix下则是最长不超过4是以最长字节为节点补齐,超过4 时 就以4的倍数为节点补齐;  回复  更多评论
  

# re: C++中的内存对齐 2014-06-18 18:07 cai
结构体中,三个short为什么是6呢,按照你的说法应该是8啊  回复  更多评论
  

# re: C++中的内存对齐 2014-07-19 13:55 hw23
配的图清晰易懂,赞一个  回复  更多评论
  

# re: C++中的内存对齐[未登录] 2014-09-14 12:02 c++
short是按照2对齐的6是对的@cai
  回复  更多评论
  

# re: C++中的内存对齐[未登录] 2014-09-14 12:03 c++
按2对齐啊@cai
  回复  更多评论
  

# re: C++中的内存对齐 2014-09-17 16:01 tq
楼主辛苦了,非常感谢  回复  更多评论
  

# re: C++中的内存对齐 2015-05-19 11:50 coat white
@牛在蓝天
补充的很好,谢谢~  回复  更多评论
  

# re: C++中的内存对齐[未登录] 2015-07-22 15:40 zc
解释的十分精辟!  回复  更多评论
  

# re: C++中的内存对齐[未登录] 2016-03-20 20:26 燕子
看过好几个内存对齐了,你的最直观!!!  回复  更多评论
  


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理