Hỏi về kích thước struct

mọi người cho em hỏi sao kích thước struct này lại là 8 byte ạ?

Bạn có thể tham khảo ở đây: here

Nhưng tóm lại cho dễ hiểu: Trong C khi cấp phát bộ nhớ cho các member của struct, thì nó cấp phát theo 4 byte một.

Ở trên thực sự chỉ dùng có 5 byte, nhưng compiler cấp phát cả 8 byte, còn vì mục đích gì thì mình cũng chưa quan tâm.

4 Likes

Bạn cũng có thể tham khảo:

4 Likes

Đây nữa. :kissing_smiling_eyes:

4 Likes

Mình thấy không phải lúc nào cũng cấp theo 4 byte một.

Ví dụ :

struct T{
double d;
bool b;
}

sẽ có kích thước 16 byte.

3 Likes

Đây là cách mình tính nhẩm do mình phịa ra :

Kích thước struct là bội kích thước lớn nhất của của các thành phần cấu tạo nên struct. Nếu thành phần là 1 mảng, một struct khác thì tính luôn loại dữ liệu cấu thành nên struct, mảng đó. Tức là bằng k * n trong đó n là kích thước loại dữ liệu lớn nhất. Tạm gọi các cụm n byte là các block.

Các phần tử được đặt gọn trong phần trống của block phía trước tại vị trí là bội kích thước cấu thành phần tử đó hoặc phải bắt đầu và nằm trong một số block tiếp theo.

Ví dụ :

struct ST{
    int aIndex;
    bool Team;
}
// phần tử lớn nhất là aIndex có kích thước 4 byte. - > Kích thước struct là bội 4
// aIndex nằm trong block 4 byte đầu tiên. Block này không còn byte trống
// Team có kích thước 1 byte phải nằm ở block tiếp theo. Block này là 4 byte thừa 3 byte
// >>> kích thức struct này là 8 byte.
struct ST{
    char buffer[100];
    double d;
}
// buffer dài 100 byte nhưng cấu tạo từ char = 1byte. d là 8 byte => kích thước struct là bội 8.
// buffer nằm trong 13 block đầu tiên vì cần 13 block = 104 mới đủ chứa buffer. 13 block này hừa 4 byte vì buffer chiếm 100 byte.
// d dài 8 byte không chứa đủ trong số byte thừa lại. Nó phải nằm trong block thứ 14  dài 8 byte. 
// >>> kích thước struct này là 14 * 8 = 112 byte;
// cái struct này khó hơn chút.
struct ST{
    char c[2];
    bool b;
    short s1;
    short s2;
    int i;
    double d;
}
// struct trên có d kích thước lớn nhất là 8 byte => struct có kích thước bội 8
// c 2 byte nằm tại block đầu tiên bắt đầu từ byte 0 đến byte 1
// b 1 byte nằm tại byte số 2
// s1 là 2 byte **tuy nhiên chú ý kích thước s là 2 bên vị trí của nó phải là bội 2 tức là nó không nằm ở byte số 3 mà nằm ở byte số 4 dến 5**.
// s2 là 2 byte tiếp theo nằm tại vị trí 6 đến 7 -> hết 1 block đầu tiên.
// i 4 byte nằm trong 4 byte đầu block thứ 2. Đến đây là cần 16 byte rồi.
// d không nằm được trong 4 byte thừa của block thứ 2. Nó phải nằm trong block thứ 3.
// >>> kích thước struct là 24. 

PS : Cái này không hoàn toàn chính xác. Nó chính xác trên các vi xử lý 64 bit. Còn 8,16,32 bit thì mình chưa test và có phát hiện không chính xác với 8,16 bit (32 bit chưa test). Đã biết nguyên nhân. Sẽ cập nhật sau nhé ! :slight_smile:

7 Likes

em cám ơn mọi người nhiều lắm ạ

Bạn phịa đúng đấy :v, mình thường test với int nên nghĩ là là bội của 4, về cơ bản mình đồng ý với cách giải thích của bạn.

3 Likes

nếu thầy câu trả lời nào hợp lý nên tich solution cho người đó bạn nha :v

đây là kiến trúc đệm (padding) trong cấp phát bộ nhớ trong c, phụ thuộc vào kiến trúc vi xử lý. Đối với vi xử lý 8bits thì mức độ truy xuất mỗi lần 1 byte nên sẽ cấp phát bộ nhớ liên tục, không có byte đệm. tương ứng với vi xử lý 32bits và hiện nay phổ biến 64bits, việc đệm các byte trống cho đủ 4bytes(32bits) hoặc 8 bytes(64bits) giúp tối ưu tốc độ xử lý khi tận dụng hết sức mạnh truy xuất bus data của vi xử lý. Hoàn toàn không phụ thuộc vào kiểu biến lớn nhất trong struct như các bạn nghĩ mà phụ thuộc vào kiến trúc bus của vi xử lý.

3 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?