2014-09-13 16 views
10

tôi đang làm việc với cấu trúc trong c trên Linux. tôi bắt đầu sử dụng các lĩnh vực bit và "đóng gói" thuộc tính và tôi đi qua một hành vi lạ:lĩnh vực chút đóng gói trong các cấu trúc c - GCC

struct t1 
{ 
    int a:12; 
    int b:32; 
    int c:4; 
}__attribute__((packed)); 

struct t2 
{ 
    int a:12; 
    int b; 
    int c:4; 
}__attribute__((packed)); 

void main() 
{ 
    printf("%d\n",sizeof(t1)); //output - 6 
    printf("%d\n",sizeof(t2)); //output - 7 
} 

Tại sao cả hai cấu trúc - đó là giống hệt nhau - mất số khác nhau của byte?

+1

Bởi vì 't2 :: b' là đảm bảo được một vị trí bộ nhớ riêng biệt? Hãy suy nghĩ về các cuộc đua dữ liệu. –

Trả lời

10
struct t1 // 6 bytes 
{ 
    int a:12; // 0:11 
    int b:32; // 12:43 
    int c:4; // 44:47 
}__attribute__((packed)); 

struct t1 // 7 bytes 
{ 
    int a:12; // 0:11 
    int b; // 16:47 
    int c:4; // 48:51 
}__attribute__((packed)); 

Thường xuyên int b phải được căn chỉnh với ranh giới byte. Vì vậy, có đệm trước nó. Nếu bạn đặt c ngay bên cạnh a đệm này sẽ không còn cần thiết. Bạn có lẽ nên làm điều này, khi truy cập các số nguyên không liên kết byte như int b:32 là chậm.

16

cấu trúc của bạn không phải là "giống hệt nhau". Cái đầu tiên của bạn có ba trường bit liên tiếp, trường thứ hai có một trường bit, một trường int (không bit), và sau đó là trường bit thứ hai.

Đây là trường quan trọng: các trường bit liên tiếp (không chiều rộng) được hợp nhất thành một vị trí bộ nhớ đơn, trong khi trường bit theo sau là trường không bit là các vị trí bộ nhớ riêng biệt.

cấu trúc đầu tiên của bạn có một vị trí bộ nhớ duy nhất, thứ hai bạn có ba. Bạn có thể lấy địa chỉ của thành viên b trong cấu trúc thứ hai của bạn, chứ không phải trong lần đầu tiên của bạn. Truy cập vào b thành viên không chạy đua với truy cập vào a hoặc c trong struct thứ hai của bạn, nhưng họ làm gì trong đầu của bạn.

Có trường không bit (hoặc trường bit có độ dài bằng không) ngay sau khi thành viên bit trường "đóng" nó trong một cảm giác, những gì theo sau sẽ là một vị trí/đối tượng bộ nhớ độc lập khác. Trình biên dịch không thể "đóng gói" thành viên b của bạn bên trong trường bit giống như trong cấu trúc đầu tiên.

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