将 char 数组转换为结构指针

Posted

技术标签:

【中文标题】将 char 数组转换为结构指针【英文标题】:Casting char array to struct pointer 【发布时间】:2018-06-11 14:23:32 【问题描述】:

我正在尝试从this code 了解以下演员表

char out_packet_buffer[4500] ;  
struct ip6_hdr *iphdr ;

iphdr = (struct ip6_hdr *) &out_packet_buffer[0]; 

struct iphdr 的成员变量存储在 char 数组 out_packet_buffer 中,我的理解是否正确?稍后在代码中,从不使用 out_packet_buffer。相反,iphdr 被 memcpyied 到一个 uint8_t 内存位置 (ether_frame)。但是 iphdr 不是 uint8_t。

如果有任何指导让我了解这里发生的事情,我将不胜感激。

谢谢

【问题讨论】:

我很确定这会破坏严格的别名。 @ChristianGibbons 感谢您指出这一点。帮助我编写改进版本的代码。 【参考方案1】:

struct iphdr 的成员变量存储在 char 数组 out_packet_buffer 中,我的理解是否正确?

有点。在这个转换中发生的事情是我们开始“查看”从&out_packet_buffer[0](或只是out_packet_buffer)开始的内存块作为struct ip6_hdr而不是char[]

iphdr 的任何后续使用都使用相同的内存,但将其拆分为 struct ip6_hdr 成员而不是 char

正如@Christian Gibbons 所说,我也认为这违反了strict aliasing 这是UB

【讨论】:

谢谢。据我了解,它为开发人员提供了对 char 缓冲区的方便且有组织的(作为结构)访问。但是,我希望 output_packet_buffer 被 memcopied 并传递给 sendto 函数,但事实并非如此。所以我没有看到 output_packet_buffer 的使用。 正是如此。这样你就可以访问iphdr->some_member而不是访问out_packet_buffer[M]out_packet_buffer[N] 然后在后面的代码中,期望将 out_packet_buffer 复制到 ether_frame 并将帧发送出去,但事实并非如此。那么为什么要使用/转换 char 数组 out_packet_buffer 呢?【参考方案2】:

看起来代码正在准备一个数据包以通过网络传输。该数据包将由一个标头和一个有效载荷组成。整个数据包大概存储在 out_packet_buffer 中。 ip6_header 结构是它的前几个字节,之后是数据负载。对标头使用结构使代码更具可读性,但在将其发送到套接字之前可能会有“结构顺序到网络顺序”函数。

无论如何,数据包只是一个字节序列,因此将其转换为任何8位类型都是可行的

【讨论】:

正确。第 588-592 行将数据包元素(IP 标头和有效负载)复制到以太网帧中,然后发送出去。然而,在第 588 行,被复制的是 iphdr。因此我根本看不到需要 out_packet_buffer。 这是一种分配大字节缓冲区的廉价方法,没有未释放指针的危险。只要它在范围内,它就会存在。也许最初的意图是将数据有效负载放在那个大缓冲区中......?仅复制 ip 标头将是比大缓冲区更小的副本。

以上是关于将 char 数组转换为结构指针的主要内容,如果未能解决你的问题,请参考以下文章

如何将 char 数组转换为结构?

ARC 不允许将非 Objective-C 指针类型“const char *”隐式转换为“id”

有没有合法的方法将 unsigned char 指针转换为 std::byte 指针?

从空字节数组转换为结构指针可能会违反严格的别名?

是否可以在 C 中将 char[] 转换为 char*?

转换为指向运行时确定大小的数组的指针