1. Các thành viên cấu trúc là kiểu dữ liệu cơ bản
Khi các thành viên của cấu trúc có kiểu dữ liệu cơ bản, địa chỉ bắt đầu của mỗi thành viên phải là bội số của kích thước kiểu dữ liệu. Nếu không, việc gán giá trị có thể không hoạt động như mong đợi.
#include <stdint.h>
#include <string.h>
typedef struct {
uint8_t fieldA;
uint16_t fieldB;
} SimpleStruct;
typedef struct {
uint8_t fieldA;
uint32_t fieldB;
} LargeStruct;
typedef struct {
uint8_t fieldA;
float fieldB;
} FloatStruct;
typedef struct {
uint8_t fieldA;
uint8_t fieldB;
} CompactStruct;
int main() {
SimpleStruct simpleInstance = {0};
LargeStruct largeInstance = {0};
FloatStruct floatInstance = {0};
CompactStruct compactInstance = {0};
printf("Kích thước của simpleInstance: %zu\n", sizeof(simpleInstance));
printf("Kích thước của largeInstance: %zu\n", sizeof(largeInstance));
printf("Kích thước của floatInstance: %zu (float size: %zu)\n", sizeof(floatInstance), sizeof(float));
printf("Kích thước của compactInstance: %zu\n", sizeof(compactInstance));
uint8_t* ptr = (uint8_t*)&simpleInstance;
uint8_t val8 = 11;
uint16_t val16 = 22;
memcpy(ptr, &val8, sizeof(val8));
memcpy(ptr + 1, &val16, sizeof(val16));
printf("Giá trị struct 1: %d %d\n", simpleInstance.fieldA, simpleInstance.fieldB);
memcpy(ptr + 2, &val16, sizeof(val16));
printf("Giá trị struct 1: %d %d\n", simpleInstance.fieldA, simpleInstance.fieldB);
ptr = (uint8_t*)&largeInstance;
uint32_t val32 = 33;
memcpy(ptr, &val8, sizeof(val8));
memcpy(ptr + 1, &val16, sizeof(val16));
printf("Giá trị struct 2: %d %d\n", largeInstance.fieldA, largeInstance.fieldB);
memcpy(ptr + 2, &val16, sizeof(val16));
printf("Giá trị struct 2: %d %d\n", largeInstance.fieldA, largeInstance.fieldB);
memcpy(ptr + 4, &val32, sizeof(val32));
printf("Giá trị struct 2: %d %d\n", largeInstance.fieldA, largeInstance.fieldB);
}
Ví dụ bộ nhớ cấu trúc: Sử dụng công cụ Debug để kiểm tra giá trị bộ nhớ và so sánh với giá trị cấu trúc.
2. Cấu trúc lồng nhau
Khi cấu trúc chứa các cấu trúc con, địa chỉ bắt đầu của cấu trúc con phải là bội số của kích thước lớn nhất trong cấu trúc con.
#include <stdint.h>
#include <string.h>
typedef struct {
uint8_t byte1;
uint8_t byte2;
uint8_t byte3;
uint8_t byte4;
uint8_t byte5;
uint8_t byte6;
uint8_t byte7;
uint8_t byte8;
} Struct8Byte;
typedef struct {
uint16_t word1;
uint16_t word2;
uint16_t word3;
uint16_t word4;
} Struct16Byte;
typedef struct {
uint32_t dword1;
uint32_t dword2;
} Struct32Byte;
typedef struct {
uint64_t qword1;
} Struct64Byte;
typedef struct {
uint8_t fieldA;
Struct8Byte nested8;
} StructWith8;
typedef struct {
uint8_t fieldA;
Struct16Byte nested16;
} StructWith16;
typedef struct {
uint8_t fieldA;
Struct32Byte nested32;
} StructWith32;
typedef struct {
uint8_t fieldA;
Struct64Byte nested64;
} StructWith64;
int main() {
StructWith8 with8 = {0};
StructWith16 with16 = {0};
StructWith32 with32 = {0};
StructWith64 with64 = {0};
printf("Kích thước with8: %zu\n", sizeof(with8));
printf("Kích thước with16: %zu\n", sizeof(with16));
printf("Kích thước with32: %zu\n", sizeof(with32));
printf("Kích thước with64: %zu\n", sizeof(with64));
size_t offset8 = (uintptr_t)&with8.nested8 - (uintptr_t)&with8;
size_t offset16 = (uintptr_t)&with16.nested16 - (uintptr_t)&with16;
size_t offset32 = (uintptr_t)&with32.nested32 - (uintptr_t)&with32;
size_t offset64 = (uintptr_t)&with64.nested64 - (uintptr_t)&with64;
printf("Địa chỉ 8-byte: 0x%p 0x%p %zu\n", &with8, &with8.nested8, offset8);
printf("Địa chỉ 16-byte: 0x%p 0x%p %zu\n", &with16, &with16.nested16, offset16);
printf("Địa chỉ 32-byte: 0x%p 0x%p %zu\n", &with32, &with32.nested32, offset32);
printf("Địa chỉ 64-byte: 0x%p 0x%p %zu\n", &with64, &with64.nested64, offset64);
uint8_t* ptr8 = (uint8_t*)&with8;
uint8_t* ptr16 = (uint8_t*)&with16;
uint8_t* ptr32 = (uint8_t*)&with32;
uint8_t* ptr64 = (uint8_t*)&with64;
uint8_t val8 = 8;
uint16_t val16 = 16;
uint32_t val32 = 32;
uint64_t val64 = 64;
memcpy(ptr8 + 1, &val8, sizeof(val8));
if (*(ptr8 + 1) == val8) {
printf("Giá trị giống val8\n");
}
memcpy(ptr16 + 2, &val16, sizeof(val16));
if (val16 == with16.nested16.word1) {
printf("Giá trị giống val16 (2) - %d == %d\n", val16, with16.nested16.word1);
} else {
printf("Giá trị khác val16 (2) - %d != %d\n", val16, with16.nested16.word1);
}
memcpy(ptr32 + 4, &val32, sizeof(val32));
if (val32 == with32.nested32.dword1) {
printf("Giá trị giống val32 (3) - %d == %d\n", val32, with32.nested32.dword1);
} else {
printf("Giá trị khác val32 (3) - %d != %d\n", val32, with32.nested32.dword1);
}
memcpy(ptr64 + 8, &val64, sizeof(val64));
if (val64 == with64.nested64.qword1) {
printf("Giá trị giống val64 (4) - %lu == %lu\n", val64, with64.nested64.qword1);
} else {
printf("Giá trị khác val64 (4) - %lu != %lu\n", val64, with64.nested64.qword1);
}
}
Khi kiểm tra con trỏ cấu trúc trỏ đến khối bộ nhớ, một số giá trị giữa không xuất hiện trong cấu trúc.
Đăng vào ngày 23 tháng 7 lúc 07:08