将char数组转换为struct *类型

时间:2018-01-04 16:00:47

标签: c arrays pointers struct casting

在下面的代码中,有人可能会解释一下struct ether_header *eh = (struct ether_header *) sendbuf;行上发生的事情吗?我知道它正在创建eh类型的指针ether_header,并且在RHS上,您将sendbuf投射为tyoe struct ether_header的指针。但是你如何才能做到这一点sendbufchar array?你也为什么要这样做?

以下是完整代码send ethernet frame

的链接
#include <arpa/inet.h>
#include <linux/if_packet.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/ether.h>

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;

2 个答案:

答案 0 :(得分:1)

  

但是如果sendbufchar数组,怎么能这样做

代码不应该这样做。

将指针转换为最初不是该类型的有效指针的类型是未定义的行为(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种数据类型的角度访问数据。也许要进行u的数据转储。

答案 1 :(得分:0)

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

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

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

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