定义了两个结构体
typedef struct Cmd {
uint8_t ua;
uint8_t ub;
uint8_t uc;
uint32_t ue;
} Cmd_t;
typedef struct Cmd_tag {
uint8_t value;
uint8_t data[1]; // 将 data 定义为指向 Cmd_t 结构体的指针
} tag_t;
在实际使用中,看见前人的代码是,new 一块内存放两个结构体。我对内存大小有些疑惑。代码如下
void test2()
{
int size = 9;
unsigned char* pdata = new unsigned char[size];
memset(pdata, 0, size);
// 解释 pdata 为 tag_t* 类型的指针
tag_t* pCmd = (tag_t*)pdata;
pCmd->value = 1;
// 将 pdata + 1 解释为 Cmd_t* 类型的指针,并将其赋给 data 成员
Cmd_t* p= (Cmd_t*)(pdata + 1);
p->ua = 10;
p->ub = 10;
p->uc = 10;
p->ue = 10;
std::cout << "value: " << static_cast<int>(pCmd->value) << std::endl;
std::cout << "Address of pCmd->value: " << static_cast<void*>(&pCmd->value) << std::endl;
std::cout << "data->a: " << static_cast<int>(p->ua) << std::endl;
std::cout << "Address of p->a: " << static_cast<void*>(&p->ua) << std::endl;
std::cout << "data->ub: " << static_cast<int>(p->ub) << std::endl;
std::cout << "Address of p->ub: " << static_cast<void*>(&p->ub) << std::endl;
std::cout << "data->uc: " << static_cast<int>(p->uc) << std::endl;
std::cout << "Address of p->uc: " << static_cast<void*>(&p->uc) << std::endl;
std::cout << "data->ue: " << p->ue << std::endl;
std::cout << "Address of p->ue: " << static_cast<void*>(&p->ue) << std::endl;
delete[] pdata;
}
输出如下
解释:
std::cout << "Size of tag_t: " << sizeof(tag_t) << " bytes" << std::endl;
std::cout << "Size of Cmd_t: " << sizeof(Cmd_t) << " bytes" << std::endl;
// Size of tag_t: 2 bytes
//Size of Cmd_t: 8 bytes
结构体 tag_t需要2 bytes
结构体 Cmd_t 需要 8 bytes
一开始我以为,new一块内存存放她两需要 2+8 =10 bytes
但是由于 将 pdata + 1 解释为 Cmd_t* 类型的指针,并将其赋给 data 成员
Cmd_t* p= (Cmd_t*)(pdata + 1);
相当于 Cmd_tag.data 和 Cmd_t.ua公用一个字节的内存
所以new的时候只需要 9 bytes
.还有一个坑:
最开始计算Cmd_t大小时 ,我以为是7bytes. 后来发现C++ 结构体在这里右4字节对齐
可以观察输出, p->ue的地址比 p->uc的地址增加了 2
所以如果代码里,size =8 程序会崩溃