2012-04-11 83 views
1

考虑如下因素片断:“的memcpy”(合并两种结构)

#define IPV4_MAX_BYTELEN 4 
struct gen_entry 
{ 
    struct in_addr addr; 
    struct in_addr mask; 
    .. 
}; 
unsigned char key[40]; 

memcpy (key, &fec->addr, IPV4_MAX_BYTELEN); 
memcpy (key + IPV4_MAX_BYTELEN, &fec->mask, IPV4_MAX_BYTELEN); 
.. 

我要的是二进制键合并这两个IP地址和子网掩码。 以这种方式合并可以吗?假设数组大小足够用于 这个目的? (或我错过了什么?)

谢谢!

+0

谢谢大家的意见! – Mark 2012-04-11 16:17:21

回答

1

这通常被称为“连接”而不是“合并”。

为便于携带,您可以明确地使用s_addr字段struct in_addr,而不是假设它是第一件事。虽然也许这是Posix保证的,但我不确定。我认为Posix也保证sizeof的IPv4地址是4个字节,所以你没问题。

你的代码不会清除数组的其他32个字节,所以它不能以任何有用的方式用作关键字。除非key在文件范围内定义,在这种情况下,它被初始化为零。

除了那些小小的小问题,我没有看到你在做什么错。

作为一个假设的可移植性问题 - 即使没有填充struct in_addrs_addr前场字节,如果有填充的值,那么你可以在理论上得到假阴性。假设你从不同的源创建了两个具有相同值但填充位不同的密钥 - 那么它们应该产生相同的密钥,但实际上不会。不过,我不担心这个问题:任何足够奇怪的实现填充整数类型的位可能太奇怪,无法提供Posix网络API。

0

是的,如果要连接in_addr结构体的第一个IPV4_MAX_BYTELEN字节的二进制值(大多数系统上是s_addr,但您仍希望明确指定它),那么可以。

如果您只想要这两个密钥,您甚至可以将密钥声明为unsigned char [IPV4_MAX_BYTELEN*2]

1

这取决于结构的大小。

考虑:

memcpy (key, &fec->addr, sizeof(fec->addr)); 
memcpy (key + sizeof(fec->addr), &fec->mask, sizeof(fec->mask)); 

为了确保您获得的所有值的结构。

密钥的大小是sizeof(fec->addr) + sizeof(fec->mask)

+0

第二个memcpy将是'key + sizeof(fec-> addr)'。另外要小心,你错过了第一个尺寸的'>' – Eregrith 2012-04-11 15:46:31

+0

@Eregrith - 感谢你发现这些错误。固定。 – gbulmer 2012-04-11 15:50:11