神奇问题:SizeOf求Record类型长度怎么会是这样?

路人丁 2004-07-26 11:33:11
结构如下:
TSendLevel = Record
FrameID : Byte; //该数据的序列 1
FrameCount :Byte; //总共的数据包 1
StaNo : array[0..9] of char; //存储站号 10
TankNo:array[0..12] of char; //存储罐号 13
OilH : Word; //液位高度 2
WaterH : Word; //水位高度 2
OilTemp : Single; //油温 4
OilVol : Single; //油体积 4
EmptyVol : Single; //空容 4
DateTime : TDateTime; //Double类型相同长度 8
End;
var
Send : TSendLevel;
使用SizeOf(Send);求出的数值是56!
单个累加计算是49
为什么?
...全文
386 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
IFindit 2004-09-07
  • 打赏
  • 举报
回复
这么长时间我也忘了,好象是一个一个放试出的,应该是连续二个single没问题,如果第三个single出现,就会多出32位即4个字节的长度!
路人丁 2004-09-06
  • 打赏
  • 举报
回复
这个贴子拖了这么久……
有个问题就是:IFindit(寻找其中的乐趣)的存放方式才符合数据长度,但是 □□□□ 让人难以理解,怎么连续空了32字节?
ExSystem 2004-07-27
  • 打赏
  • 举报
回复
Delphi自己对齐的…
参见:《Delphi面向对象编程思想》
IFindit 2004-07-27
  • 打赏
  • 举报
回复
■■■■
■■■■
■■■■
■■■■
■■■■
■■■■
■■■□
■■■■
■■□□
■■■■
■■■■
□□□□
■■■■
■■■■
wizardqi 2004-07-27
  • 打赏
  • 举报
回复
编译器在默认情况下使用了DWORD对齐,使程序数据可以更快速的存取。
beyondtkl 2004-07-27
  • 打赏
  • 举报
回复
字节对齐造成的 一般默认为4BYTE对齐的<在WIN32系统下>
getit911 2004-07-27
  • 打赏
  • 举报
回复
record对齐造成的。
huayuxing 2004-07-27
  • 打赏
  • 举报
回复
TSendLevel =Packed Record
你要用压缩过的RECORD,否则他会自动对齐到最大的属性里去的,
IFindit 2004-07-27
  • 打赏
  • 举报
回复
把你的结构全部注释掉,然后一个一个放开, 看ShowmessageBox的值, 对比上图,就全明白了!
IFindit 2004-07-27
  • 打赏
  • 举报
回复
以上结构在内存中是这样排列的,实心为数据, 空心为Delphi自动添补的,你可以发现规律:

■■■■
■■■■
■■■■
■■■■
■■■■
■■■■
■■■□
■■■■
■■□□
■■■■
■■■■
■■■■

stubborndonkey 2004-07-27
  • 打赏
  • 举报
回复
不加PACKED编译器就自动把每个成员按32位边界对齐,以达到最快的存取速度。
exu 2004-07-26
  • 打赏
  • 举报
回复
说得比较乱,凑合看吧。

没错,Record和Packed Record的区别就在这里。
Record最小的内存分配时32位(32位系统)。
而Packed Record是按照实际位分配的。
在Delphi的windows单元中,你会发现很多Packed record,而且申明非常特殊。
例如TWMSYSCOMMAND,这个申明是为了给程序员更直观方便的方法来映射WM_SYSCOMMAND,实际上这个申明和TMessage完全一样(位),而程序员也可以通过LOWORD和HIWORD来获得参数。
aiirii 2004-07-26
  • 打赏
  • 举报
回复
packed Record

Record
一个是紧凑式的,一个是松散对齐的, 所以大小不对
aiirii 2004-07-26
  • 打赏
  • 举报
回复


type
TSendLevel = packed Record
FrameID : Byte; //该数据的序列 1
FrameCount :Byte; //总共的数据包 1
StaNo : array[0..9] of char; //存储站号 10
TankNo:array[0..12] of char; //存储罐号 13
OilH : Word; //液位高度 2
WaterH : Word; //水位高度 2
OilTemp : Single; //油温 4
OilVol : Single; //油体积 4
EmptyVol : Single; //空容 4
DateTime : TDateTime; //Double类型相同长度 8
End;

var
Send : TSendLevel;
begin
showMessage(IntToStr(sizeOf(send)));
end;

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧