2013-02-28 26 views
6

Tôi đang cố gắng sử dụng các trường bit trong C++ để đạt được kích thước lớp cụ thể, nhưng vì lý do nào đó nó lớn hơn tôi mong đợi.Thuộc tính không được chỉ định sử dụng các trường bit trong lớp C++

Vấn đề là, một lớp có 32 bit (4 byte) đang báo cáo (khi được chuyển làm đối số đến sizeof) 5 byte. Ví dụ lớp dưới đây:

typedef unsigned char u8; 
typedef unsigned int u32; 

class Test { 
    u8 four_bit_field : 4; 
    u8 eight_bit_field; 
    u32 twenty_bit_field : 20; 
}__attribute__((packed)); 

Nếu các vị trí four_bit_fieldeight_bit_field được bật, sizeof trả lại kích thước phù hợp, 4 byte. Tôi tin rằng đó là một vấn đề liên quan đến bộ nhớ.

Vì vậy, ai đó biết lý do đằng sau hành vi này? Và, quan trọng nhất, làm thế nào tôi có thể sửa lỗi này, mà không cần chuyển bất kỳ vị trí nào.

Trả lời

10

Trường u8 không có số bit được căn chỉnh với ranh giới byte tiếp theo, thay vì được đóng gói với các trường bit khác. Vì vậy, 4 bit đầu tiên của bạn lấy một byte, 8 bit thứ hai lấy một byte và 20 bit cuối cùng mất 3 byte, tổng cộng 5.

Nếu bạn thêm kích thước trường bit vào trường 8 bit, nó sẽ hoạt động, xem http://ideone.com/Bexw6l

+0

Đó là những gì tôi nghĩ khi tôi nói điều này là một vấn đề bộ nhớ allignment. Nhưng tôi đang tìm một giải pháp cho vấn đề này. – braunmagrin

+0

@braunmagrin, tôi đang bận thử nghiệm giải pháp, xem chỉnh sửa của tôi. –

+0

Tôi xin lỗi vì đã vội vàng. Cảm ơn, điều đó đã được giải quyết. – braunmagrin

2

Thực ra đó là vấn đề liên kết. u8 eight_bit_field không phải là một bitfield, nó là một đồng bằng unsigned char (từ tên), và char, signed char hoặc unsigned char được căn chỉnh tự nhiên trên một ranh giới byte.

Do đó, bạn kết thúc với 4 các khoảng đệm giữa các kích thước four_bit_fieldeight_bit_field4 các phần đệm sau twenty_bit_field; cái thứ hai có thể tái sử dụng bởi một lớp dẫn xuất, cái cũ mãi mãi bị mất.

2

Hãy thử buộc sự liên kết tới 1 byte:

#pragma pack(1) 
class Test { 
    u8 four_bit_field : 4; 
    u8 eight_bit_field : 8; 
    u32 twenty_bit_field : 20; 
}; 
#pragma pack() 
+0

Cảm ơn, tôi không biết về chỉ thị '# pragma'. Luôn học ... – braunmagrin

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