'memcpy'(合并两个结构)

时间:2012-04-11 15:36:59

标签: c networking

考虑下面的片段:

#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地址和掩码。 如果数组大小足够,可以用这种方式合并它 这个目的? (或者我错过了什么?)

谢谢!

3 个答案:

答案 0 :(得分:1)

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

为了便于移植,您可以明确使用s_addr的{​​{1}}字段,而不是假设它是第一件事。虽然Posix可能保证这一点,但我不确定。我认为Posix还保证struct in_addr一个IPv4地址是4个字节,所以你就可以了。

您的代码不会清除数组的其他32个字节,因此无法以任何有用的方式将其用作密钥。除非在文件范围定义sizeof,否则它将初始化为零。

除了那些小小的琐事之外,我认为你所做的事情没有任何问题。

作为假设的可移植性问题 - 即使在key的{​​{1}}字段之前没有填充字节,如果有填充在价值中,你理论上可以得到假阴性。假设您从不同的源构造了两个具有相同值但填充位不同的密钥 - 那么它们应该产生相同的密钥,但事实上并非如此。不过我不担心:任何实现奇怪的整数类型的填充位都可能太奇怪了,无法提供Posix网络API。

答案 1 :(得分:1)

这取决于结构的大小。

考虑:

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

确保获得结构中的所有值。

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

答案 2 :(得分:0)

是的,如果你想连接in_addr结构的第一个IPV4_MAX_BYTELEN字节的二进制值(大多数系统上的s_addr,但你仍然想明确指定它),那就没关系。

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