具体来说,这出现在讨论中:
记忆消耗明智,使用
struct
两个int
的内存是否有可能比仅仅int
两个内存更多?
或者,用语言来说:
#include <iostream>
struct S { int a, b; };
int main() {
std::cout << (sizeof(S) > sizeof(int) * 2 ? "bigger" : "the same") << std::endl;
}
是否有任何合理的 1 (不一定是普通或当前)环境,这个小程序会打印bigger
?
1 为了澄清,我在这里所指的是以一些有意义的数量开发和生产的系统(和编译器),特别是不是为了证明这一点而构建的理论示例,或一次性原型或爱好者创作。
答案 0 :(得分:17)
是否有任何合理的(不一定是常见的或最新的)环境,这个小程序会打印得更大?
不是我知道的。我知道not completely reassuring,但我有理由相信,由于C ++标准的要求,没有这样的环境。
在符合标准的†编译器中,如下所示:
从(1)和(3)可以得出,类型的对齐小于或等于其大小。如果它更大,则数组需要添加填充以使其所有元素对齐。出于同样的原因,类型的大小始终是其对齐的整数倍。
这意味着在给定的结构中,第二个成员将始终正确对齐 - 无论int的大小和对齐 - 如果放置在第一个成员之后,即不需要填充填充。在此布局下,struct的大小也已经是其对齐的倍数,因此也不需要尾随填充。
我们可以选择不符合标准的(大小,对齐)值,这使得此结构需要任何形式的填充。
任何这样的填充都需要不同的目的。但是,这样的目的似乎难以捉摸。假设由于某种原因需要这个填充的环境。无论填充的原因是什么,它都可能适用于数组,但是从(1)我们知道它不能。
但是假设这样的环境确实存在,我们需要一个C ++编译器。它可以通过简单地使int更大,即通过将填充放在内部来支持数组中额外需要的填充。这反过来又会允许结构与两个整数的大小相同,并让我们没有理由添加填充。
†一个编译器 - 即使是一个不符合标准的编译器 - 可以解决任何这些错误,这可能是错误的,所以我会忽略它们。
‡我想在数组和结构都是原语的环境中,可能存在一些基本的区别,它们允许我们使用无填充数组和填充结构,但同样,我使用了don't know of any such thing。
答案 1 :(得分:3)
在您的具体示例struct S { int a, b; };
中,我看不到任何合理的填充参数。 int
应该已经自然对齐,如果是,int *
可以而且应该是指针的自然表示,并且S *
不需要有任何不同。但总的来说:
一些罕见的系统具有不同表示的指针,例如, int *
表示为表示“字”地址的整数,char *
是字地址和字节偏移的组合(其中字节偏移存储在其他不需要的高位中)字地址)。通过加载单词,然后屏蔽和移位以获得正确的字节,在软件中取消引用char *
。
在这样的实现中,确保所有结构类型具有最小对齐可能是有意义的,即使对于结构的成员不是必需的,只是为了使指向该结构的指针不需要该字节偏移混乱。意味着给定struct S { char a, b; };
,sizeof(S) > 2
是合理的。具体来说,我希望sizeof(S) == sizeof(int)
。
我从未亲自使用过这样的实现,因此我不知道它们是否确实产生了这样的填充。但是这样做的实现是合理的,并且至少非常接近现有的实际实现。
答案 2 :(得分:2)
我知道这不是你要求的,它不符合你的问题的精神(因为你可能有标准的布局类),但严格地回答这一部分:
内存消耗明智,是否有可能使用结构 两个整数比两个整数占用更多的内存?
答案是有点......是的:
struct S
{
int a;
int b;
virtual ~S() = default;
};
讽刺地指出C ++没有结构,它有类。 struct
是一个引入类的声明/定义的关键字。
答案 3 :(得分:2)
只能访问64位块内存的系统可能有一个选项可以使用32位&#34; int&#34;并不是完全不可信的。与可能被uint32_t绊倒的其他程序兼容的大小提升为更大的类型。在这样的系统上,一个偶数个&#34; int&#34;值可能没有额外的填充,但具有奇数个值的值可能会这样做。
从实际角度来看,具有两个int值的结构需要填充的唯一方法是,如果结构的对齐多于两倍于&#34; int&#的粗略结果34 ;.这反过来要求结构的对齐比64位粗,或者int的大小小于32位。后一种情况本身并不常见,但是将两者结合起来会使结构对齐比int对齐粗两倍以上似乎非常奇怪。
答案 4 :(得分:0)
理论上填充用于提供访问内存区域的有效方法。如果将填充添加到2个整数变量会增加效率,而不是它可以有填充。但实际上我没有遇到任何具有2个整数的结构填充位。