Hỏi về địa chỉ khi compiler cấp phát vùng nhớ

Mọi người cho e hỏi khi compiler cấp phát bộ nhớ cho tất cả các loại biến: char, short, int, long hay long long thì đều cấp phát tại các địa chỉ chẵn đúng ko ạ.

Không nhé.

4 Likes

2 posts were split to a new topic: Tại sao kích cỡ của struct là 8 byte?

Không có hỏi hộ, hỏi ké, hỏi luôn tiện thể ở đây nhé.

A post was removed

e thấy a có đưa ra link này [Chia sẻ] Data structure alignment & padding. Thì trong đây có dòng này “Chúng ta đều biết rằng các CPU hiện đại của chúng ta luôn thao tác trên memory theo từng khối ở địa chỉ là một số chẵn, không thể thao tác trên địa chỉ là số lẻ được. Như vậy với mstruct của chúng ta, ví dụ biến “char c” nằm trên memory có địa chỉ chẵn, nếu biến “int i” nằm kế tiếp thì sẽ có địa chỉ lẻ rất phức tạp để CPU thao tác với biến “int i” này”
Nhưng trên kia a lại trả lời là không.
A có thể giải thích hộ e đc ko ạ.

2 Likes

Mấu chốt là ở chỗ này chỉ nói về biến kiểu int, nên nó đúng. Còn câu hỏi ban đầu của bạn là tất cả nên là nó sai.

Mà thật ra, trong bài chia sẻ kia, cũng có nhiều điểm chưa rõ ràng và hợp lý cho lắm, bạn nên xem cả các bình luận phía sau đó nữa để có cái nhìn tổng quan và chính xác hơn nhé.

4 Likes

char có thể nằm ở địa chỉ là số lẻ (alignas(1)).

5 Likes

E cảm ơn. E hỏi a thêm 1 chỗ nữa ạ

struct packet
{
uint8_t crc; //1 byte
uint8_t status; //1
uint16_t payload; //2
uint8_t bat;  //1
uint8_t sensor; //1
uint8_t lastAddr; //1
};

E chạy nhiều lần thì thấy địa chỉ thằng uint8_t crc; đầu tiên luôn ở địa chỉ chẵn, thằng tiếp sau thì lẻ rồi. Ko biết do ngẫu nhiên hay do nó phải thế a nhỉ

Không có gì là ngẫu nhiên cả đâu bạn. Địa chỉ thằng đầu tiên cũng chính là địa chỉ của struct trong bộ nhớ, do đó nó luôn phải ở địa chỉ chẵn. Hay nói đúng hơn là nó phải nằm ở địa chỉ tuân theo 1 word của CPU. Các phần tử tiếp theo có thể không cần địa chỉ chẵn là vì các phần tử trong một struct luôn có sự liên kết với nhau và luôn nằm nối tiếp nhau do đó CPU có thể đoán được cần phải fetch cùng 1 lúc thay vì fetch từng phần tử

5 Likes

uint8_t status cũng chỉ cần có thế thôi, nó chỉ có 1 byte mà.

Kiểm tra lại: Nguyên tắc là trình biên dịch không được thay đổi thứ tự các thành phần trong khai báo struct. Nếu thành phần liền sau bị lẻ (misaligned) thì thành phần liền trước phải độn vào (padding) số byte vừa đủ để thành phần liền sau vào đúng vị trí. Đến thành phần cuối cùng nếu sizeof không chia hết cho alignof thì độn thêm vào để nó chẵn.

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