将char数组转换为struct *类型

在下面的代码中,有人可能会解释行struct ether_header *eh = (struct ether_header *) sendbuf;上发生了什么struct ether_header *eh = (struct ether_header *) sendbuf; ? 我知道它正在创建一个类型为ether_header的指针eh ,并且在RHS上,您正在将sendbuf转换为tyoe struct ether_header的指针。 但是你怎么能这样做是sendbuf是一个char array ? 你也为什么要这样做?

这是完整代码发送以太网帧的链接

 #include  #include  #include  #include  #include  #include  #include  #include  #include  int main(int argc, char *argv[]) { int sockfd; struct ifreq if_idx; struct ifreq if_mac; int tx_len = 0; char sendbuf[BUF_SIZ]; struct ether_header *eh = (struct ether_header *) sendbuf; 

但是,如果sendbuf是一个char数组,你怎么做呢?

代码不应该这样做。

将指针转换为最初不是该类型的有效指针的类型是未定义的行为 (UB)。

 char sendbuf[BUF_SIZ]; struct ether_header *eh = (struct ether_header *) sendbuf; // UB 

至少要考虑struct ether_header是否有一个对齐要求是偶数地址, sendbuf[]从奇数地址开始的。 任务可能会导致程序失效。

第二个问题是未发布的代码以后可能会使用sendbuf[]eh ,这可能会违反严格的别名规则@Andrew Henle 。


更好的方法是使用union 。 现在成员已对齐,并且union处理严格的别名规则。

 union { char sendbuf[BUF_SIZ]; struct ether_header eh; } u; 

你也为什么要这样做?

允许从2种数据类型的角度访问数据。 也许是为了进行数据转储。

char sendbuf[BUF_SIZ]分配一个字符块(即大多数系统上的字节)和转换struct ether_header *eh = (struct ether_header *) sendbuf表示您明确要将其视为struct ether_header类型。 除了(可能)设置CPU寄存器之外,没有来自此演员的重要指令。

你最终会得到两个指向同一块内存的指针。 修改一个会影响另一个。

话虽如此,它并不完全正确/安全,因为sendbuf可能无法正确对齐以实际包含struct ether_header

编辑:关于结构别名规则,显式允许char*为任何其他数据类型设置别名,但反过来不一定正确。