Đối với các câu trả lời được cung cấp, có vẻ như có một số nhầm lẫn về những gì căn chỉnh thực sự là. Sự nhầm lẫn có thể phát sinh bởi vì có 2 loại căn chỉnh.
1. alignment Member
Đây là một biện pháp định tính mà giải thích rõ ràng như thế nào lớn một thể hiện là trong số byte cho một trật tự cụ thể của các thành viên trong kiểu cấu trúc/lớp. Nói chung, các trình biên dịch có thể cấu trúc nhỏ gọn/các thể hiện lớp nếu các thành viên được sắp xếp theo kích thước byte của chúng theo thứ tự giảm dần (tức là lớn nhất đầu tiên, các thành viên nhỏ nhất cuối cùng) trong cấu trúc. Hãy xem xét:
struct A
{
char c; float f; short s;
};
struct B
{
float f; short s; char c;
};
Cả hai cấu trúc đều chứa chính xác cùng một thông tin. Vì lợi ích của ví dụ này; loại float mất 4 byte, loại ngắn mất 2 và ký tự mất 1 byte. Tuy nhiên, cấu trúc đầu tiên A có các thành viên theo thứ tự ngẫu nhiên, trong khi cấu trúc thứ hai B yêu cầu các thành viên theo kích thước byte của chúng (điều này có thể khác với kiến trúc nhất định, tôi giả sử kiến trúc CPU intel x86 với sự liên kết 4 byte trong ví dụ này). Bây giờ xem xét kích thước của các cấu trúc:
printf("size of A: %d", sizeof (A)); // size of A: 12;
printf("size of B: %d", sizeof (B)); // size of B: 8;
Nếu bạn mong chờ kích thước là 7 byte, bạn sẽ được giả định rằng các thành viên là đóng gói vào cấu trúc bằng cách sử dụng một liên kết 1-byte. Trong khi một số trình biên dịch cho phép điều này, nói chung hầu hết các trình biên dịch sử dụng 4-byte hoặc thậm chí 8-byte sắp xếp do lý do lịch sử (hầu hết CPU làm việc với DWORD (double-word) hoặc QWORD (quad-word) mục đích chung đăng ký).
Có 2 cơ chế đệm tại nơi làm việc để đạt được đóng gói.
Thứ nhất, mỗi thành viên có kích thước nhỏ hơn so với byte byte-alignment là 'sáp nhập' với thành viên tiếp theo (s) nếu kết quả kích thước byte là nhỏ hơn hoặc bằng byte-alignment. Trong cấu trúc B, các thành viên s và c có thể được sáp nhập theo cách này; kích thước kết hợp của chúng là 2 byte cho s + 1 byte cho c == 3 byte < = căn chỉnh 4 byte. Đối với cấu trúc A, không có sự hợp nhất như vậy có thể xảy ra, và mỗi thành viên tiêu thụ hiệu quả 4 byte trong bao bì của cấu trúc.
Tổng kích thước của cấu trúc lại được đệm để cấu trúc tiếp theo có thể bắt đầu tại ranh giới căn chỉnh. Trong ví dụ B tổng số byte sẽ là 7. Ranh giới 4 byte tiếp theo nằm ở byte 8, do đó cấu trúc được đệm với 1 byte để cho phép phân bổ mảng như là một chuỗi các trường hợp chặt chẽ.
Lưu ý rằng Visual C++/GCC cho phép sắp xếp khác nhau của 1 byte, 2 và bội số cao hơn 2 byte.Hiểu rằng điều này làm việc với khả năng của trình biên dịch của bạn để tạo ra mã tối ưu cho kiến trúc của bạn. Thật vậy, trong ví dụ sau, mỗi byte sẽ được đọc dưới dạng một byte đơn bằng cách sử dụng lệnh một byte cho mỗi thao tác đọc. Trong thực tế, phần cứng vẫn sẽ lấy toàn bộ dòng bộ nhớ chứa mỗi byte đọc vào bộ đệm, và thực hiện lệnh 4 lần, ngay cả khi 4 byte nằm trong cùng một DWORD và có thể được nạp trong thanh ghi CPU trong 1 lệnh.
#pragma pack(push,1)
struct Bad
{
char a,b,c,d;
};
#pragma pack(pop)
2. alignment Allocation
này liên quan chặt chẽ với các cơ chế đệm thứ 2 được giải thích trong phần trước, tuy nhiên, một llocation sắp xếp có thể được quy định trong các biến thể của malloc/memalloc chức năng phân bổ. Do đó, có thể phân bổ một đối tượng tại một ranh giới liên kết khác nhau (thường cao hơn 2) so với liên kết byte của cấu trúc/kiểu đối tượng gợi ý.
size_t blockAlignment = 4*1024; // 4K page block alignment
void* block = malloc(sizeof(T) * count, blockAlignment);
Mã sẽ đặt khối các trường hợp đếm kiểu T trên các địa chỉ kết thúc vào bội số của 4096.
Lý do cho việc sử dụng sự sắp xếp, phân bổ như vậy một lần nữa hoàn toàn kiến trúc. Ví dụ, việc đọc và viết các khối từ các địa chỉ liên kết trang nhanh hơn vì phạm vi địa chỉ vừa với các lớp bộ đệm. Các phạm vi được phân tách trên các trang 'thùng rác' khác nhau trong bộ nhớ cache khi vượt qua ranh giới trang. Các phương tiện khác nhau (các kiến trúc bus) có các mẫu truy cập khác nhau và có thể hưởng lợi từ các sự sắp xếp khác nhau. Nói chung, sự sắp xếp các kích thước trang 4, 16, 32 và 64 K không phải là hiếm.
thử lại bằng các cấu trúc thay vì các kiểu gốc. –
'Trả về căn chỉnh theo byte (lũy thừa số nguyên là hai) cho bất kỳ thể hiện nào của kiểu đã cho' - http://en.cppreference.com/w/cpp/language/alignof. 'sizeof' chỉ cho kích thước, tính bằng byte, tất nhiên. – chris
Có thể đáng nhắc đến - [sizeof luôn là bội số của alignof] (http://stackoverflow.com/questions/4637774/is-the-size-of-a-struct-required-to-be-an-exact-multiple -of-the-alignment-of-tha) – Steve314