Google
 
欢迎光临
  发起投票 | 发起主题  
2000-11-24
男
帖子数: 1063
发帖数前500位(399)

 
在网络通讯里面一直会牵涉到字节对齐问题,
请问,
字节对齐的策略是什么,是怎么对齐的??
请高手指教!

因为某一个struct在不同的字节对齐方式下,极有可能得到不同的内存组织方式//



 

与子偕老 执子之手 都是我的最爱

2001-11-07 15:50 第 1 楼 回复 | 引用 | 编辑 | | Top

2000-11-24
男
帖子数: 1063
发帖数前500位(399)

 
请高手指教//

【在 cyber (小小蓝牙) 的大作中提到:】
在网络通讯里面一直会牵涉到字节对齐问题,
请问,
字节对齐的...

与子偕老 执子之手 都是我的最爱

2001-11-07 19:17 第 2 楼 回复 | 引用 | 编辑 | | Top

1999-05-13
帖子数: 1009
发帖数前500位(419)

 
字节对齐,一般总是把一个结构凑足偶数位,便于编译器优化编译,或是为了其它特殊需要。有些是凑足4字节或8字节的整数倍。为了解决不同平台或编译器下的进程通讯问题,
就在结构里添加一个字段,指明结构的大小。

struct {
DWORD dwSize;
...
} s;

初始化的时候,先指定大小:

s.dwSize = sizeof s;

这样不同平台,或不同编译器下生成的程序就可以根据这个字段得知整个结构的实际大小了。

【在 cyber (小小蓝牙) 的大作中提到:】
在网络通讯里面一直会牵涉到字节对齐问题,
请问,
字节对齐的...

欲求无限 立地成佛 . 有时候 交谈变得空洞 沉默却像沟通

2001-11-08 08:32 第 3 楼 回复 | 引用 | 编辑 | | Top

2000-11-24
男
帖子数: 1063
发帖数前500位(399)

 
可是要取结构里某些字段怎么办??
不同的字节对齐,
字段的起始位置很有可能是不一样的//

【在 modico (modico) 的大作中提到:】
字节对齐,一般总是把一个结构凑足偶数位,便于编译器优化编译,或是...

与子偕老 执子之手 都是我的最爱

2001-11-08 12:37 第 4 楼 回复 | 引用 | 编辑 | | Top

1999-05-13
帖子数: 1009
发帖数前500位(419)

 
对齐一般都是后补齐,就是追加补齐的意思,这样起始位置就总是一样的了。
有哪个编译器是前补的?

【在 cyber (小小蓝牙) 的大作中提到:】
可是要取结构里某些字段怎么办??
不同的字节对齐,
字段的起...

欲求无限 立地成佛 . 有时候 交谈变得空洞 沉默却像沟通

2001-11-08 12:52 第 5 楼 回复 | 引用 | 编辑 | | Top

2000-11-24
男
帖子数: 1063
发帖数前500位(399)

 
比如:
struct _s
{
char c1[11];
int i;
}
如果接收方把这段字符流类型强制转换为struct _s以后,
s.i的起始地址很可能不一样.
我的意思就是这样,
如果把int i放在这个结构的前面就不会有这个问题了,
但我的结构里如果是字符放在前面,就会出现这种情况了。

也许可以设计为与字节对齐无关,
但需要知道对齐时编译器处理的细节,
这个我就一点都没有头绪了//

【在 modico (modico) 的大作中提到:】
对齐一般都是后补齐,就是追加补齐的意思,这样起始位置就总是一样的...

与子偕老 执子之手 都是我的最爱

2001-11-08 13:00 第 6 楼 回复 | 引用 | 编辑 | | Top

1999-05-13
帖子数: 1009
发帖数前500位(419)

 
对齐是对整个结构来说的,不是针对结构里的成员变量的。
所以 sizeof(s.c1) 仍然是11,但是 sizeof(s) 却不是 11+4=15,而变成16了。

【在 cyber (小小蓝牙) 的大作中提到:】
比如:
struct _s
{
char c1[11]...

欲求无限 立地成佛 . 有时候 交谈变得空洞 沉默却像沟通

2001-11-08 13:07 第 7 楼 回复 | 引用 | 编辑 | | Top

2000-11-24
男
帖子数: 1063
发帖数前500位(399)

 

比如:
typedef struct DataPool
{
long lDataType; /*type of data*/
char cWatchID[11]; /*ID of watch*/
char cData[20]; /*data*/
float fOriginalData1;
float fOriginalData2;
float fOriginalData3;
float fOriginalData4;
long lDataQuility;
}SDataPool;
/* Description: struct of Data Pool
*/
也就是再加上一个 int iSize;
然后组织成SDataPool sDataPool[100]的时候,
只要每个sDataPool[i].iSize = sizeof(SDataPool);
接受的时候,指针只要往后移动sDataPool[i].iSize 取下一个就行了?

阿,有点领悟了,谢谢modico

【在 modico (modico) 的大作中提到:】
对齐是对整个结构来说的,不是针对结构里的成员变量的。
所以 s...

※编辑: cyber 于 2001-11-8 13:21:24 在 [202.117.83.16] 编辑本文

与子偕老 执子之手 都是我的最爱

2001-11-08 13:20 第 8 楼 回复 | 引用 | 编辑 | | Top

1999-05-13
帖子数: 1009
发帖数前500位(419)

 
right.

【在 cyber (小小蓝牙) 的大作中提到:】

比如:
typedef struct DataPool
...

欲求无限 立地成佛 . 有时候 交谈变得空洞 沉默却像沟通

2001-11-08 13:31 第 9 楼 回复 | 引用 | 编辑 | | Top

2000-11-24
男
帖子数: 1063
发帖数前500位(399)

 
thank you very much~~~~~~~

【在 modico (modico) 的大作中提到:】
right.

【在 cyber (小小蓝牙) 的大作中提到...

与子偕老 执子之手 都是我的最爱

2001-11-08 13:38 第 10 楼 回复 | 引用 | 编辑 | | Top

2000-11-24
男
帖子数: 1063
发帖数前500位(399)

 
modico,也许是我对字节对齐这个术语理解错了,
但现在有一个问题,如:
#include "stdafx.h"
#include "stdio.h"

typedef struct _s
{
char c[9];
int i;
}S;


int main(int argc, char* argv[])
{
S s;
int i = (char *)&s.i - (char *)s.c;
printf("%d\n",i);
return 0;
}
8 bytes 对齐以后的结果是:12
1 bytes 对齐以后的结果是:9
如果在发送方A,以1 bytes 对齐,
数据到达B以后,用8 bytes 对齐方式进行类型强制转换后取数值,
s.i的值就会有问题//

请问如何在socket传输中避免这个问题的出现??
望指教.


【在 modico (modico) 的大作中提到:】
对齐是对整个结构来说的,不是针对结构里的成员变量的。
所以 s...

与子偕老 执子之手 都是我的最爱

2001-11-08 19:03 第 11 楼 回复 | 引用 | 编辑 | | Top

2000-10-19
帖子数: 74
无等级(0)

 
字节对齐的目的在于提高CPU的处理性能,MSDN有说,
A misaligned 4-byte data member, which is on an address that is not a multiple of four, causes a performance penalty with an 80386 processor and a hardware exception with a MIPS® RISC processor. In the latter case, although the system handles the exception, the performance penalty is significantly greater.
注意到所谓的"performance penalty",简单的理解是,处理器在存取内存时,对不同的内存起始地址会有不同的存取效率,比如对偶地址存取一个字只需要一个时钟周期,而对于奇地址则需要两个时钟周期。因此,对于 C 这种与物理系统关系紧密的语言,编译器就需要考虑在内存中的地址对齐问题,以提高处理效率。比如如下的代码
void fun()
{
char c;
int i;
c = 1;
i = 1;
}
编译器在将其翻译成机器码时就会使用字节对齐,上述代码的赋值语句在VC中的编译结果如下(未优化)
00401028 mov byte ptr [ebp-4],1
0040102C mov dword ptr [ebp-8],1
其中 ebp 为当前函数栈的基地址指针,从中可以看到 c 和 i 在内存中都占据了4字节(尽管sizeof( c ) 为 1)。

关于在结构中的字节对齐问题,我正在考察,或许能再发表些议论。

以上只是我的个人见解,欢迎批评指正。



【在 cyber (小小蓝牙) 的大作中提到:】
modico,也许是我对字节对齐这个术语理解错了,
但现在有一...

2001-11-08 23:02 第 12 楼 回复 | 引用 | 编辑 | | Top

1999-05-13
帖子数: 1009
发帖数前500位(419)

 
其实是我错了。对不起。
尤其这句话是大错:“对齐是对整个结构来说的,不是针对结构里的成员变量的。”
请大家尽快把这句话从你的印象中抹去,这是我造的垃圾。
可能是对测试的例子有些偶然巧合了,所以得出的结论看起来居然还能自圆其说。

以下是另外一种看法,供您参考:

结构里,其实不管结构还是直接在栈上定义的变量都一样。所以我试着就你给的例子和前一篇文章中的例子做一个解释。

规则是:不同的数据类型有不同的对齐要求,char 可以在任意地址,也就是1-byte对齐;16位变量,如short,在偶数地址对齐;32位变量如int,float在4-byte地址边界对齐......依次类推,变量(非组合式变量,如struct,union)总是对齐在与它大小一致的地址边界上,不管这些变量是独立变量,还是包含在 struct 里的。

我们的例子:
struct {
char c[9];
int i;
}s;

如果 s 的起始地址(&s)是 0,那么因为 char 可以在任意地址边界,所以 c[8] 的地址是落在偏移为8的偶数地址上的;因为 int 必须在 4-byte 边界上,所以它不能落在偏移9的位置,而只能落在最接近的偏移12的位置,偏离了正常位置3个字节。能够偏离的最大位置是有限制的,就是编译器里设置的值。Win32平台上通常是8。就是说调整结构里成员的地址偏移时,最多可以偏离8个字节的位置。

前一篇文章(#2245)中所说的在栈上定义的变量也是如此:

void fun()
{
char c;
int i;
.......
}

变量 i 确实相对 c 偏移了4字节而不是1字节,因为 ebp-4 是在4字节边界上对齐的,虽然 c 可以落在任意地址上,但是 i 却非要落到4-byte边界上不可,因此 i 必须在 ebp-8 上。

上述两种情况下,i 的偏移,都不是 char 的缘故,而是它自身的需要的缘故。

所以要解决你提出来的不同平台间进程通讯的问题,设计结构各成员变量的大小及顺序是要讲究一下的,我觉得一般可以遵循这样一个公式:

对结构中的任意一个成员变量 mv, 其前面所有的变量大小总和应该刚好是 mv 的大小的整数倍。

比如,对于上面的结构,char 最好定义成 12,这样 i 可以不用偏移了。如果有好几个 char,则尽量放在一起。


【在 cyber (小小蓝牙) 的大作中提到:】
modico,也许是我对字节对齐这个术语理解错了,
但现在有一...

欲求无限 立地成佛 . 有时候 交谈变得空洞 沉默却像沟通

2001-11-09 16:22 第 13 楼 回复 | 引用 | 编辑 | | Top

2000-11-24
男
帖子数: 1063
发帖数前500位(399)

 
这个解释合理,
比msdn要详细多了 :)

谢谢,modico的热心解答。
谢谢所有参与的朋友!

【在 modico (modico) 的大作中提到:】
其实是我错了。对不起。
尤其这句话是大错:“对齐是对整个结构来...

与子偕老 执子之手 都是我的最爱

2001-11-09 22:56 第 14 楼 回复 | 引用 | 编辑 | | Top

2008-11-25
女
嗖的一声,周六又快来啦!
帖子数: 1433
发帖数前500位(281)

 
2001年原来OL也有交流技术的,欣慰啊


2009-06-16 09:47 第 15 楼 回复 | 引用 | 编辑 | | Top

2006-12-22
男
想要飞得更高,就该把地平线忘掉!
帖子数: 4009
发帖数前75位(73)

 
哇 2001.。。。。。。。

-———————————————————————————————————————————————————-
Good morning,and in case i dont see you,good afternoon,good evening and good night!

2009-06-16 09:48 第 16 楼 回复 | 引用 | 编辑 | | Top

2005-10-23
男
非常之累
帖子数: 1467
发帖数前500位(270)

 
我记得05年的时候,ol上有很多资源,真是丰富多彩
后来有一段时间没上,上来就只剩下论坛和博客了
记得以前还有相册呢,还有软件下载区什么的

有事业的人是能把自己不太喜欢的工作也做的精彩的人。

2009-06-16 09:49 第 17 楼 回复 | 引用 | 编辑 | | Top

2005-10-01
帖子数: 46
无等级(0)

 
如果在VC下的话,要解决的很简单
在定义结构体之前加上伪指令

#pragma pack(push)
#pragma pack (1)

struct mystruct
{

*******************


}

#pragma pack(pop)

2009-07-04 01:16 第 18 楼 回复 | 引用 | 编辑 | | Top

  1. 主页
  2. »
  3. 论坛首页
  4. »
  5. 科技文化
  6. »
  7. IT技术
  8. »
  9. 字节对齐问题
 



Powered By Openlab v3.0 (Debug Build: 1.28817) © 2010. 页面执行: 0.125秒. 内存使用: 331.6MB. 25 次数据库查询.

京ICP备05050892号