Panic的小屋

国破山河在,城春草木深。
随笔 - 152, 评论 - 1764, 引用 - 25, 文章 - 0

导航

公告

<2010年3月>
28123456
78910111213
14151617181920
21222324252627
28293031123
45678910

留言簿(336)

随笔分类

随笔档案

文章档案

相册

国外好站推荐

工具网页

我的其他网页

我的网友

户外运动

美女的空间

搜索

最新评论

阅读排行榜

评论排行榜

结构体对齐的具体含义(#pragma pack)

Posted on 2005-04-02 23:49 Panic 阅读(18705) 评论(43)  编辑 收藏

结构体对齐的具体含义(#pragma pack)

作者:panic 2005年4月2日

还是来自csdn的帖子:
主  题:   探讨:内存对齐
作  者:   typedef_chen ((名未定)(我要骗人))
等  级:   
信 誉 值:   100
所属论坛:   C/C++ C++ 语言
问题点数:   50
回复次数:   1
发表时间:   2005-04-02 22:53:27
  
  
朋友帖了如下一段代码:
  #pragma pack(4)
  class TestB
  {
  public:
    int aa;
    char a;
    short b;
    char c;
  };
  int nSize = sizeof(TestB);
  这里nSize结果为12,在预料之中。

  现在去掉第一个成员变量为如下代码:
  #pragma pack(4)
  class TestC
  {
  public:
    char a;
    short b;
    char c;
  };
  int nSize = sizeof(TestC);
  按照正常的填充方式nSize的结果应该是8,为什么结果显示nSize为6呢?

事实上,很多人对#pragma pack的理解是错误的。
#pragma pack规定的对齐长度,实际使用的规则是:
结构,联合,或者类的数据成员,第一个放在偏移为0的地方,以后每个数据成员的对齐,按照#pragma pack指定的数值和这个数据成员自身长度中,比较小的那个进行。
也就是说,当#pragma pack的值等于或超过所有数据成员长度的时候,这个值的大小将不产生任何效果。
而结构整体的对齐,则按照结构体中最大的数据成员 和 #pragma pack指定值 之间,较小的那个进行。

具体解释
#pragma pack(4)
  class TestB
  {
  public:
    int aa; //第一个成员,放在[0,3]偏移的位置,
    char a; //第二个成员,自身长为1,#pragma pack(4),取小值,也就是1,所以这个成员按一字节对齐,放在偏移[4]的位置。
    short b; //第三个成员,自身长2,#pragma pack(4),取2,按2字节对齐,所以放在偏移[6,7]的位置。
    char c; //第四个,自身长为1,放在[8]的位置。
  };
这个类实际占据的内存空间是9字节
类之间的对齐,是按照类内部最大的成员的长度,和#pragma pack规定的值之中较小的一个对齐的。
所以这个例子中,类之间对齐的长度是min(sizeof(int),4),也就是4。
9按照4字节圆整的结果是12,所以sizeof(TestB)是12。


如果
#pragma pack(2)
    class TestB
  {
  public:
    int aa; //第一个成员,放在[0,3]偏移的位置,
    char a; //第二个成员,自身长为1,#pragma pack(4),取小值,也就是1,所以这个成员按一字节对齐,放在偏移[4]的位置。
    short b; //第三个成员,自身长2,#pragma pack(4),取2,按2字节对齐,所以放在偏移[6,7]的位置。
    char c; //第四个,自身长为1,放在[8]的位置。
  };
//可以看出,上面的位置完全没有变化,只是类之间改为按2字节对齐,9按2圆整的结果是10。
//所以 sizeof(TestB)是10。

最后看原贴:
现在去掉第一个成员变量为如下代码:
  #pragma pack(4)
  class TestC
  {
  public:
    char a;//第一个成员,放在[0]偏移的位置,
    short b;//第二个成员,自身长2,#pragma pack(4),取2,按2字节对齐,所以放在偏移[2,3]的位置。
    char c;//第三个,自身长为1,放在[4]的位置。
  };
//整个类的大小是5字节,按照min(sizeof(short),4)字节对齐,也就是2字节对齐,结果是6
//所以sizeof(TestC)是6。

感谢 Michael 提出疑问,在此补充:

当数据定义中出现__declspec( align() )时,指定类型的对齐长度还要用自身长度和这里指定的数值比较,然后取其中较大的。最终类/结构的对齐长度也需要和这个数值比较,然后取其中较大的。

可以这样理解, __declspec( align() ) 和 #pragma pack是一对兄弟,前者规定了对齐的最小值,后者规定了对齐的最大值,两者同时出现时,前者拥有更高的优先级。
__declspec( align() )的一个特点是,它仅仅规定了数据对齐的位置,而没有规定数据实际占用的内存长度,当指定的数据被放置在确定的位置之后,其后的数据填充仍然是按照#pragma pack规定的方式填充的,这时候类/结构的实际大小和内存格局的规则是这样的:
在__declspec( align() )之前,数据按照#pragma pack规定的方式填充,如前所述。当遇到__declspec( align() )的时候,首先寻找距离当前偏移向后最近的对齐点(满足对齐长度为max(数据自身长度,指定值) ),然后把被指定的数据类型从这个点开始填充,其后的数据类型从它的后面开始,仍然按照#pragma pack填充,直到遇到下一个__declspec( align() )。
当所有数据填充完毕,把结构的整体对齐数值和__declspec( align() )规定的值做比较,取其中较大的作为整个结构的对齐长度。
特别的,当__declspec( align() )指定的数值比对应类型长度小的时候,这个指定不起作用。

Feedback

# re: 结构体对齐的具体含义(#pragma pack)

2005-04-03 17:17 by dlutyuanhongl
已阅。

# re: 结构体对齐的具体含义(#pragma pack)

2005-04-07 08:38 by lostpencil
感激,终于明白了

# re: 结构体对齐的具体含义(#pragma pack)

2005-04-07 23:10 by 乾坤一笑
关于pragma,不得不帖得一个广告!

http://blog.vckbase.com/smileonce/archive/2005/04/07/4494.html

# 请教一句话的翻译

2005-04-20 17:56 by susan
'%$S': actual alignment (%d) is greater than the value specified in __declspec(align())
请帮我看看这句话应当怎样翻,先谢过了。
“实际对齐”这种说法可以让人接受吗?

# re: susan

2005-04-21 09:17 by pAnic
实际的对齐参数比 __declspec(align())中指定的要大一些?

# 谢谢先!问号表示不确定吗?

2005-04-21 11:32 by susan
谢谢先!问号表示不确定吗?

# re: 结构体对齐的具体含义(#pragma pack)

2005-04-21 14:01 by Panic
不是很确定:P
不过意思是对的啦。

# re: 结构体对齐的具体含义(#pragma pack)

2005-05-27 15:27 by Rocky
不错!

# 有一点问题

2005-06-09 19:21 by Michael
类之间的对齐,是按照类内部最大的成员的长度,和#pragma pack规定的值之"中较小的一个对齐的。"

此结论对定义有__declspec(align(CACHE_LINE))
不成立。

#define CACHE_LINE  16
#define CACHE_ALIGN __declspec(align(CACHE_LINE))
struct S
{
   char a;
   CACHE_ALIGN double d;
   double f;
   char g;
};

# re:Michael

2005-06-09 19:54 by pAnic
__declspec( align() )是强制指定其后的类型以 指定数值 和 类型自身长度 之中的最大值来对齐。
前面的描述没有考虑这种情况。

当数据定义中出现__declspec( align() )时,指定类型的对齐长度还要用自身长度和这里指定的数值比较,然后取其中较大的。最终类/结构的长度也需要和这个数值比较,然后取其中较大的。

# re: pAnic

2005-06-10 12:51 by Michael
You are right. 
This article is good.

# re: Michael

2005-06-10 16:54 by pAnic
thanks~

# re: 结构体对齐的具体含义(#pragma pack)

2005-12-31 15:56 by question
我还有个问题就是
struct  a
{
int id;
char length;
char ip[16];
};
这个为什么是24

# re: 结构体对齐的具体含义(#pragma pack)

2006-06-02 11:55 by yihect
char ip[16] 相当于 16句 char ch;  ?????

这样倒是 24 

# re: 结构体对齐的具体含义(#pragma pack)

2006-08-03 10:56 by laowu
"nt aa; //第一个成员,放在[0,3]偏移的位置,
    char a; //第二个成员,自身长为1,#pragma pack(4),取小值,也就是1,所以这个成员按一字节对齐,放在偏移[4]的位置。
    short b; //第三个成员,自身长2,#pragma pack(4),取2,按2字节对齐,所以放在偏移[6,7]的位置。
    char c; //第四个,自身长为1,放在[8]的位置"
那请问[5]在哪里呀?

# re: 结构体对齐的具体含义(#pragma pack)

2006-12-14 17:05 by 1234567
不能同意楼主的说法,楼住说的有问题,完全是想当然!

# re: 结构体对齐的具体含义(#pragma pack)

2007-01-17 20:51 by 笑斩清风
//2007.1.18 字节对齐
#pragma pack(4)
typedef struct _ST001
{
int aa; //0-3
char a;//1:4 按1字节对齐,4
int b;   //4:4 按4字节对齐,
char c;//2:4 按2字节对齐
}ST001;
class C001
{
public:
int aa;
char a;//1:4 按1字节对齐
int b; //4:4 按4字节对齐
char c;//2:4 按2字节对齐
};
#pragma pack()
typedef struct _ST002
{
int aa;
char a;
int b;
char c;
}ST002;
class C002
{
public:
int aa;
char a;//1:4 按1字节对齐
int b; //4:4 按4字节对齐
char c;//2:4 按2字节对齐
};

main()
{
//2007.1.18 字节对齐
printf("Struct:%d,%d\nClass:%d,%d",sizeof(ST001),sizeof(ST002),sizeof(C001),sizeof(C002));
getch();
}

输出结果:
Struct:16,16
Class:16,16

如改为#pragma pack(2)
输出结果为:
Struct:12,16
Class:12,16

测试环境:VC6,默认对齐:8

与楼主的贴子不符啊.

# re: 结构体对齐的具体含义(#pragma pack)

2007-01-17 20:53 by 笑斩清风
汗一个.

[把本来是short的b定义成int了]

# re: 结构体对齐的具体含义(#pragma pack)

2007-03-28 13:05 by 朵朵
8错 8错 长知识

# re: 结构体对齐的具体含义(#pragma pack)

2007-04-17 21:56 by 苯鸟
感谢楼主!

# re: 结构体对齐的具体含义(#pragma pack)

2007-05-17 17:05 by aa
找了好久,因为这个东东,与一个好公司错过了,早看到就好了

# fvvxdiqs

2007-08-25 20:51 by fvvxdiqs
 <a href="http://kuqeziyd.com">odnatlog</a>  holibvwo http://qycjreiy.com ydqatsju relbwywe  [URL=http://muhvwvcm.com]symzgjss[/URL] 

# re: 结构体对齐的具体含义(#pragma pack)

2007-09-18 15:56 by 同声传译翻译官
谢谢,很有启发

# re: 结构体对齐的具体含义(#pragma pack)

2008-02-29 10:21 by 米威
明白了,感谢,支持 !

# hodicjcm

2009-09-08 02:36 by hodicjcm
 <a href="http://vnsoyjat.com">xhavwcth</a>  [URL=http://lhqojlff.com]xruucuos[/URL]  vwwusodk http://yuseftra.com tvbccsve inrhofqd 

# cheap fioricet adenoidectomy subrogation

2009-09-10 03:56 by cheap fioricet adenoidectomy subrogation
You have to have funny faces and words, you can't just have words. It is a powerful thing, and I think that's why it's hard for people to imagine that women can do that, be that powerful.

# buy adipex online

2009-09-10 03:57 by buy adipex online
Winning is important to me, but what brings me real joy is the experience of being fully engaged in whatever I'm doing.

# retin

2009-09-10 07:33 by retin
Nothing is more conducive to peace of mind than not having any opinions at all.

# finasteride

2009-09-10 10:46 by finasteride
The nice thing about egotists is that they don't talk about other people.

# generic xanax

2009-09-10 10:49 by generic xanax
See things as they are and write about them. Don?t waste your creative energy trying to make things up. Even if you are writing fiction, write the things you see and know.

# alprazolam online

2009-09-10 10:50 by alprazolam online
Marriage is the only adventure open to the cowardly.

# generic norvasc gumbrine logician

2009-09-10 10:58 by generic norvasc gumbrine logician
The only way to get rid of a temptation is to yield to it.

# cheap adipex

2009-09-10 14:59 by cheap adipex
Deeds, not words shall speak me.

# norvasc

2009-09-10 15:03 by norvasc
When you close your doors, and make darkness within, remember never to say that you are alone, for you are not alone; nay, God is within, and your genius is within. And what need have they of light to see what you are doing?

# awnyvfon

2009-09-10 21:39 by awnyvfon
 <a href="http://txpmoese.com">pfddyjfs</a>  [URL=http://wmpzfcwi.com]oawpqckc[/URL]  rvbiqpiq http://nhjznzjo.com jwetkgkq ahxnicnm 

# cheap levitra

2009-09-11 02:49 by cheap levitra
I often quote myself. It adds spice to my conversation.

# esomeprazole

2009-09-11 02:52 by esomeprazole
It is your work in life that is the ultimate seduction.

# esomeprazole

2009-09-11 02:53 by esomeprazole
Funny business, a woman's career: the things you drop on the way up the ladder so you can move faster. You forget you'll need them again when you get back to being a woman. It's one career all females have in common, whether we like it or not: being a woman. Sooner or later, we've got to work at it, no matter how many other careers we've had or wanted.

# anticollineation

2009-09-11 02:56 by anticollineation
My theory of evolution is that Darwin was adopted.

# would

2009-09-11 02:56 by would
If one sticks too rigidly to one's principles, one would hardly see anybody.

# lumdwbbr

2009-09-11 10:36 by lumdwbbr
dyndnzbr http://eengxlua.com rflfzlfo svgbjfog
标题  
姓名  
主页
验证码 *
内容   
  登录  使用高级评论  Top
[使用Ctrl+Enter键可以直接提交]