T1 = record
b1,b2:Boolean;
ID:Integer;
v2:Extended; // 10
end; T2 = record
b1,b2:Boolean;
ID:Integer;
v1:array [0..9] of Byte; // 10
end;SizeOf(Extended) = 10SizeOf(T1) = 24 ?????
SizeOf(T2) = 20可以将以上两个结构写入文件中用 UltraEdit 看。
T1 中最后多出了4个字节,我无法理解。
我一直以后,是4字节一分配。
够的话,接在后面,
不够的时候,再开4字节。哪位高手能解释,为什么两个结构体,得到的大小不一样。
(Delphi2007 + WinXP)
b1,b2:Boolean;
ID:Integer;
v2:Extended; // 10
end; T2 = record
b1,b2:Boolean;
ID:Integer;
v1:array [0..9] of Byte; // 10
end;SizeOf(Extended) = 10SizeOf(T1) = 24 ?????
SizeOf(T2) = 20可以将以上两个结构写入文件中用 UltraEdit 看。
T1 中最后多出了4个字节,我无法理解。
我一直以后,是4字节一分配。
够的话,接在后面,
不够的时候,再开4字节。哪位高手能解释,为什么两个结构体,得到的大小不一样。
(Delphi2007 + WinXP)
解决方案 »
- Delphi7怎么在代码里判断插入的值是主键,然后提示重新输入啊?
- 求Delphi版标准3DES算法源码?
- 新手求助带函数的select语句如何写?
- 提问一个有关MSCOMM控件的小问题?
- 字典搜索算法——高手请进
- 为什么Delphi写的ActiveForm,被delphi调用时,Tab等DialogKey无效
- 如何从outlook中导入地址簿的数据
- 在用了Pchar后,编译时怎么老是提示Warning!
- 高手挑站:菜鸟大放100分,如何在自己已有的特色上再继承其它FORM,使得在设计期间,就可看到被继承窗体的控件?
- 旬Activex 例程。500分
- Delphi UThreadsPool使用的问题
- 关于fastreport 求救
Record field alignment
Controls alignment of fields in Delphi record types and class structures. Click the down-arrow to select from the possible values: If you select option Off (equivalent to {$A1}) or disable the option (equivalent to {$A-}), fields are never aligned. All record and class structures are packed. If you select Byte (equivalent to {$A2}), fields in record types that are declared without the packed modifier and fields in class structures are aligned on byte boundaries. If you select Word (equivalent to {$A2}), fields in record types that are declared without the packed modifier and fields in class structures are aligned on word boundaries. If you select Double Word (equivalent to {$A4}), fields in record types that are declared without the packed modifier and fields in class structures are aligned on double-word boundaries. If you select Quad Word (equivalent to {$A8} or {$A+}), fields in record types that are declared without the packed modifier and fields in class structures are aligned on quad word boundaries. Regardless of the state of the $A directive, variables and typed constants are always aligned for optimal access. Execution is faster if you set the option to 8 (Quad Word).
This is the default.
4.1.1 Alignment of Words, Doublewords, Quadwords, and Double Quadwords
Words, doublewords, and quadwords do not need to be aligned in memory on natural boundaries. The natural boundaries for words, double words, and quadwords are even-numbered addresses, addresses evenly divisible by four, and addresses evenly divisible by eight, respectively. However, to improve the performance of programs, data structures (especially stacks) should be aligned on natural boundaries whenever possible. The reason for this is that the processor requires two memory accesses to make an unaligned memory access; aligned accesses require only one memory access. A word or doubleword operand that crosses a 4-byte boundary or a quadword operand that crosses an 8-byte boundary is considered unaligned and requires two separate memory bus cycles for access.所以默认的对齐策略是:结构中的每一个成员,都能够对应到相应的 natural boundary。
v2 宽度是10字节,它的 natural boundary 是被8整除(因为 x86 通用寄存器和 x87 浮点寄存器不需要更大的对齐数)。在 v2 之后也要有额外的用于对齐字节的原因是:如果不保留额外的空间,当使用该结构体的数组时,将无法保证数组中每个该成员都能够对齐到 natural boundary。因此,它的结构是:
00~00 b1
01~01 b2
02~03 2 bytes alignment
04~07 ID
08~17 v2
18~23 6 bytes alignment由于 v1 的每个成员都是1字节,实际上是不需要为 v1 作出任何调整的,哪怕它的偏移量是奇数;但该结构中最大的 natural boundary 是4(ID),所以整个结构体会增加额外的字节,以保证即使在该结构的数组中,ID 仍然是对齐的:
00~00 b1
01~01 b2
02~03 2 bytes alignment
04~07 ID
08~17 v1
18~19 2 bytes alignment
1.数据类型自身的对齐值:
对于char型数据,其自身对齐值为1,byte型为1,int为4,Extended为10,单位字节。
2.结构体或者类的自身对齐值:其成员中自身对齐值最大的那个值。
3.指定对齐值:delphi编译器中配置的值,一般为1,2,4,8。
4.数据成员、结构体和类的有效对齐值:自身对齐值和指定对齐值中小的那个值。知道了上面四个概念
假设delphi编译器指定的值为8
来分析T1和T2
对于T1:
T1 = record
b1,b2:Boolean;
ID:Integer;
v2:Extended; // 10
end;首先b1自身对齐值1,指定值8,有效值为1,存在第1个位置
b1自身对齐值1,指定值8,有效值为1,存在第2个位置
ID自身对齐值4,指定值8,有效值为4,存在第5-8的位置(4的倍数)
v2自身对齐值10,指定值8,有效值为8,存在第9-18的位置
结束,再看整个结构体T1的自身对齐值为其中最大的值为10,指定值8,有效值为8,所以要根据8的整数倍进行圆整,我们已经存了18个,其后补6个字节进行圆整即变为24个字节。对于T2:
T2 = record
b1,b2:Boolean;
ID:Integer;
v1:array [0..9] of Byte; // 10
end;首先b1自身对齐值1,指定值8,有效值为1,存在第1个位置
b1自身对齐值1,指定值8,有效值为1,存在第2个位置
ID自身对齐值4,指定值8,有效值为4,存在第5-8的位置(4的倍数)
v1按10个byte存,自身对齐值为1,指定值8,有效值为1,存在第9-18的位置
结束,再看整个结构体T2的自身对齐值为其中最大的值为4,指定值8,有效值为4,所以要根据4的整数倍进行圆整,我们已经存了18个,其后补2个字节进行圆整即变为20个字节。结果
T1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
b1 b2 id id id id v2 v2 v2 v2 v2 v2 v2 v2 v2 v2 T2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
b1 b2 id id id id v1 v1 v1 v1 v1 v1 v1 v1 v1 v1
其实按照这样的结构体进行对比看更容易
T1 = record
b1:Boolean;
ID:Integer;
b2:Boolean;
end;T2 = record
ID:Integer;
b1:Boolean;
b2:Boolean;
end;域中只是顺序变化了下
然而sizeof(t1)=12;sizeof(t2)=8
v2:Extended; // 10
b1,b2:Boolean;
ID:Integer;
end;按 yqdragon(小布点) 点的理论这个就是16 。 确实不错
#9 说的编译器,我想应该是 Project / Options / Complier / record field alignment
不瞒大家,我在写字段解析的代码。
就是可以根据 delphi 的声明文字,得到某个文件里的一条条记录。
先就这样,继续研究。