在代码审查期间,我遇到了一些代码,它们定义了如下的简单结构:
class foo {
unsigned char a;
unsigned char b;
unsigned char c;
}在其他地方,定义了这些对象的数组:
foo listOfFoos[SOME_NUM];随后,这些结构被原始复制到一个缓冲区中:
memcpy(pBuff,listOfFoos,3*SOME_NUM);此代码依赖于以下假设: a.)foo的大小为3,不应用填充,b)这些对象的数组被打包,它们之间没有填充。
我在两个平台(RedHat 64b,Solaris9)上用GNU尝试过它,它在这两个平台上都能工作。
上述假设有效吗?如果不是,在什么情况下(例如,操作系统/编译器中的更改)可能会失败?
发布于 2009-11-05 04:30:54
对象的数组需要是连续的,所以对象之间永远不会有填充,尽管填充可以添加到对象的末尾(产生几乎相同的效果)。
考虑到您正在使用char,这些假设可能通常是正确的,但是C++标准肯定不能保证这一点。不同的编译器,甚至只是传递给当前编译器的标志的更改,都可能导致在结构的元素之间插入填充,或者在结构的最后一个元素之后插入填充,或者两者都插入。
发布于 2009-11-05 04:29:19
这样做肯定会更安全:
sizeof(foo) * SOME_NUM发布于 2009-11-05 04:40:23
如果像这样复制数组,应该使用
memcpy(pBuff,listOfFoos,sizeof(listOfFoos));只要您将pBuff分配到相同的大小,这将始终起作用。通过这种方式,您根本不需要对填充和对齐进行任何假设。
大多数编译器将结构或类与所包含的最大类型的所需对齐方式对齐。在字符的情况下,这意味着没有对齐和填充,但如果添加一个短字符,例如,您的类将是6个字节大小,并在最后一个字符和短字符之间添加一个字节的填充。
https://stackoverflow.com/questions/1676385
复制相似问题