【问题标题】:C++ sizeof with boolC++ sizeof 与 bool
【发布时间】:2012-10-02 01:04:19
【问题描述】:

这是一个简单的问题。先写代码。

struct A {
    int x; 
};
struct B {
    bool y;
};
struct C {
    int x;
    bool y;
};

在主函数中,我调用

cout << " bool : " << sizeof(bool) <<
     "\n int : " << sizeof(int) <<
     "\n class A : " << sizeof(A) <<
     "\n class B : " << sizeof(B) <<
     "\n class C : " << sizeof(C) << "\n";

结果是

bool : 1
int : 4
class A : 4
class B : 1
class C : 8

为什么 C 类的大小是 8 而不是 5? 请注意,这是在 MINGW 4.7 / Windows 7 / 32 位机器中使用 gcc 编译的。

【问题讨论】:

  • @Marlon 那么,填充的主要目的是什么?
  • @Sungmin:想想数组。
  • 额外的空间是padding,但目的是alignment:大多数架构更适合对齐访问数据,所以一个32位的@987654325 @ 对齐到 4 个字节比未对齐的内存访问更快(有时甚至是原子的)。在某些架构中情况更糟,您不能直接使用未对齐的类型。

标签: c++ boolean sizeof


【解决方案1】:

聚合的对齐是它最严格的成员(具有最大对齐要求的成员)的对齐。换句话说,结构的大小是其最严格(具有最大对齐要求)成员对齐的倍数。

struct D
{
  bool a;
  // will be padded with char[7]
  double b; // the largest alignment requirement (8 bytes in my environment)
};

上述结构的大小将是 16 个字节,因为 16 是 8 的倍数。在您的示例中,最严格的类型是 int 对齐到 4 个字节。这就是结构被填充为 8 个字节的原因。我再举一个例子:

struct E
{
  int a;
  // padded with char[4]
  double b;
};

上面结构的大小是 16。16 是 8 的倍数(在我的环境中对齐双精度)。

我写了一篇关于内存对齐的博客文章以获得更详细的解释 http://evpo.wordpress.com/2014/01/25/memory-alignment-of-structures-and-classes-in-c-2/

【讨论】:

  • 不是最长的类型;它是对齐方式“最严格”(即最长)的类型的对齐方式。例如,在许多 ABI 中,double 的长度为 8 字节,但仅对齐 4 字节。 (理论上,它应该是所有对齐的 LCM,但标准要求“每个对齐值应是 2 的非负整数幂”(3.11,第 4 段),因此您可以取最长的一个。)
  • 如果struct中有struct怎么办。
  • @M.kazemAkhgary 结构体的对齐要求将与 double 等普通数据类型一样考虑。
【解决方案2】:

将结构对齐到一个字的大小,这里是 4 个字节。

【讨论】:

  • 我可以再问一下吗?对齐结构的原因是什么?
  • 这并没有解释对齐策略或者可能是答案不完整。如果它与 4 对齐,那么 struct B 也将是 4 个字节。但是,它的大小是 1 个字节。同样在我的回答中,我证明了编译器与 8 个字节对齐,而不再是 4 个字节。我的观点是,它将结构的大小与其包含的最大类型的倍数对齐。这更好地解释了它。
【解决方案3】:

查看结构的定义,您有 1 个字节的值,后跟 4 个字节的整数。该整数需要在 4 字节边界上分配,这将强制编译器在 1 字节布尔值之后插入 3 字节填充。这使得结构的大小为 8 个字节。为避免这种情况,您可以更改结构中元素的顺序。

同样对于返回不同值的两个 sizeof 调用,您确定您在这里没有拼写错误,并且您没有使用指针大小或不同类型或某些整数变量。

由 Rohit J 在struct size is different from typedef version?回答

【讨论】:

  • 在我的例子中,改变结构 C 中元素的顺序并不会影响结果。
  • @Sungmin:成员的顺序通常不会影响填充。考虑如果int必须对齐到一个4字节的边界,可以排序为bool,padding,int;或intbool、填充。请注意,在数组中,每个元素位于前一个元素之外的 sizeof(type) 个字节。
  • @Sungmin:你是对的。在这种情况下,更改顺序不会改变struct 的大小。
猜你喜欢
  • 2012-08-27
  • 1970-01-01
  • 2011-06-21
  • 2013-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多