将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*
为任何其他数据类型设置别名,但反过来不一定正确。