2012-03-21 26 views
8

tôi có mã tiếp theo:Tại sao kích thước của bản ghi không bằng với tổng kích cỡ của các trường?

type TRecord1 = record 
    myarr: array [0..31] of single: 
end; 
type TRecord2 = record 
    b1, b2, b3, b4, b5, b6: byte; 
end; 
type TRecord3 = record 
    myarr: array [0..31] of single:  
    b1, b2, b3, b4, b5, b6: byte; 
end; 

procedure TForm1.FormCreate(Sender: Tobject); 
begin 
    ShowMessage(IntToStr(SizeOf(TRecord1))+'+'+IntToStr(SizeOf(TRecord2))+ 
     '='+IntToStr(SizeOf(TRecord3))); 
end; 

Chương trình hiển thị thông báo sau:

128+6=136 

Tại sao SizeOf(TRecord3) bằng 136 chứ không phải 134?

+0

quy tắc chung: nếu bạn định sử dụng một số cấu trúc có tệp - hãy khai báo chúng là 'đóng gói'. – OnTheFly

+2

Quy tắc ngón tay cái của tôi sẽ không bao giờ viết biểu diễn nhị phân của hồ sơ vào tệp –

+0

Có tránh lưu trữ dữ liệu nhị phân, nhưng chỉ thị đóng gói có sử dụng khi các bản ghi được truyền trong I/O (dll, giao tiếp nối tiếp, v.v.). Sử dụng các kỹ thuật chuyển đổi chuỗi nhị phân/chuẩn hóa nên được áp dụng cho phát triển mới. –

Trả lời

15

Điều này là do phần đệm được thêm do căn chỉnh bản ghi. TRecord3 có căn chỉnh 4 vì nó chứa giá trị single. Và do đó đệm được thêm vào cuối bản ghi để làm cho kích thước chính xác là bội số của 4. Đó là lý do kích thước là 136 thay vì giá trị 134 mà bạn mong đợi.

Bạn có thể khai báo hồ sơ của mình thành packed hoặc tương đương, đặt tùy chọn trình biên dịch căn chỉnh thành $ALIGN 1. Với sự liên kết của 1 sẽ không có phần đệm được thêm vào bản ghi và SizeOf(TRecord3)=134. Tuy nhiên, tôi khuyên bạn không nên làm điều này. Sử dụng kết quả căn chỉnh tự nhiên trong việc truy cập bộ nhớ hiệu quả nhất cho các bản ghi. Ví dụ, nó đắt hơn cho bộ vi xử lý để tải một giá trị lệch hơn là tải một giá trị liên kết. Đối với một số single hoặc integer, căn chỉnh tự nhiên nằm trên biên độ 4 byte. Đối với double căn chỉnh tự nhiên nằm trên ranh giới 8 byte và cứ tiếp tục như vậy. Bạn nên sử dụng các bản ghi đóng gói nếu bạn cần khả năng tương thích nhị phân với một thư viện khác sử dụng các bản ghi được đóng gói.

+2

ngoài ra, bạn có thể thay đổi khai báo thành 'loại TRecord3 = bản ghi đóng gói ...' để ngăn việc căn chỉnh bản ghi, mặc dù thông thường bạn không cần. Các bản ghi được sắp xếp hoạt động tốt hơn, nhưng trong một số trường hợp, bạn có thể cần các bản ghi được đóng gói. – GolezTrol

4

Điều này là do căn chỉnh. Các trường trong bản ghi được căn chỉnh trên 4 byte hoặc 8 byte (hoặc byte khi chỉ byte được sử dụng trong bản ghi.) Theo cách sao cho bản ghi khi trong một mảng tất cả các trường sẽ tiếp tục được căn chỉnh. Nếu bạn muốn công thức hoạt động, bạn nên sử dụng 'bản ghi đóng gói'. Xin lưu ý rằng các trường có thể không có dấu và có thể cản trở hiệu suất.

Các vấn đề liên quan