2013-08-17 34 views
5

Tôi đã một struct định nghĩa là:Tại sao offsetof (thành viên) bằng sizeof (struct)?

struct smth 
{ 
    char a; 
    int b[]; 
}; 

Khi tôi gọi sizeofoffsetof trên struct này:

cout << sizeof(struct smth) << endl; 
cout << offsetof(struct smth, b) << endl; 

Output là:

4 
4 

Tại sao khi kích thước của stuct là 4 và char đang sử dụng 1 byte, độ lệch của mảng int là 4? Tại sao có một số loại đệm? Ngoài ra, tại sao mảng int không chiếm bất kỳ không gian nào?

+1

Bạn có nghĩa là 'offsetof (struct smth, b)', phải không? –

+0

@CarlNorum Vâng, tôi có. Đã chỉnh sửa. – bugra

+2

Có phải C hoặc C++ không? Họ khác nhau. –

Trả lời

8

Làm cách nào khi kích thước của đường ống là 4 và char sử dụng 1 byte, độ lệch của mảng int là 4? Tại sao có một số loại đệm?

Có đệm vì tiêu chuẩn C cho phép; trình biên dịch thường sắp xếp các biến để cải thiện hiệu suất.

Ngoài ra, tại sao biến thứ hai không chiếm bất kỳ không gian nào (có vẻ như trường hợp này)?

Đây là thành viên mảng linh hoạt C99 - đó là toàn bộ điểm của nó. Ý tưởng là phân bổ cấu trúc của bạn như sau:

struct smth *s = malloc(sizeof *s + 10 * sizeof s->b[0]); 

Và sau đó bạn có cấu trúc hoạt động như thể b là mảng 10 phần tử.

+0

Loại cải thiện hiệu suất nào cho phép điều này? Chỉ tò mò thôi. – bugra

+0

@ biox6, một số hướng dẫn tải bộ vi xử lý chỉ có thể tải các từ từ các địa chỉ được căn chỉnh từ. Nếu bạn có một từ tại một địa chỉ chưa được ký, bạn cần tải từng byte riêng lẻ và kết hợp lại. –

+0

Báo cáo phân bổ của bạn không xem xét ràng buộc căn chỉnh. Nói chung nó sẽ không phân bổ số lượng bộ nhớ chính xác. Thay vào đó, bạn sẽ cấp phát một cấu trúc có kích thước phù hợp bằng cách sử dụng 'struct smth * s = malloc (offsetof (struct smth, b [10])); – IInspectable

3

Do kích thước của thành viên b bằng 0 và trình biên dịch thêm đệm giữa các thành viên ab để b nằm trên ranh giới "từ".

Tuy nhiên, nếu tôi nhớ chính xác có một mảng linh hoạt trong cấu trúc như vậy chỉ là C hợp lệ, không phải C++ ngoại trừ phần mở rộng của trình biên dịch.

+0

đây là 'int b []' tương đương với int * b? – Light

+2

Không, không. 'int * b' sẽ làm cho' sizeof (smth) 'lớn hơn, và khoảng trống thừa sẽ là địa chỉ của một số biến int được lưu trữ. Thay vào đó, 'int b []' nói cấu trúc sẽ được phân bổ động với một số số nguyên (không biết tại thời gian biên dịch) số nguyên như một khối bộ nhớ duy nhất. – mity

+0

@mity Làm thế nào để bạn gán (các) giá trị cho biến 'b', bạn có thể cho tôi câu lệnh gán – Light

2

Kể từ OP bình luận rằng vấn đề là C++:

struct smth 
{ 
    char a; 
    int b[]; 
}; 

Một mảng như b[] không hợp lệ trong C++. Mảng phải có kích thước cố định. Các mảng chiều dài biến chỉ hợp lệ trong C99.

Giả sử rằng trình biên dịch của bạn hỗ trợ nó làm phần mở rộng, mảng b[] có kích thước bằng 0, làm cho cấu trúc chỉ chứa thành viên char. Quy tắc đệm trong struct hoạt động, đệm struct vào một từ, là 4 byte trong máy của bạn.

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