【问题标题】:Why does my object take up 64 bytes and not 32?为什么我的对象占用 64 个字节而不是 32 个字节?
【发布时间】:2009-11-17 15:01:52
【问题描述】:

我有一堂课是这样的:

class myType
{

  union {
      float data[4];
      other_vector4_type v
  } ;
  typedef union {
      float data[4];
      other_vector4_type v
  } myType-internal_t;

 <various member functions, operator overloads>

}

现在我想在我的顶点缓冲区中使用这种类型,但 sizeof() 不是预期的那样。我将类对齐到 16 个字节。

sizeof(myType) 产生 64。

sizeof(myType::myType-internal_t) 产生 32。

我已经阅读了很多关于数据对齐的文章,但我不知道我在哪里使用了额外的数据。我尝试剥离自定义构造函数,但它保持不变,将 struct 的 class 关键字交换也不会改变它(我不明白它的用途,因为它发生了!)

这很烦人,我现在将使用 internal 类型,因为我不会经常接触数据,但是让类按我想要的方式工作会很棒。

【问题讨论】:

  • 告诉我们 other_vector_type 的样子。
  • 你应该让你的问题的代码部分更清楚......
  • 一个完整的测试用例(编译并使用正确的语法)将有助于解决真正的问题。
  • myType-internal_t 在我看来是个很可疑的名字。 -'s 甚至允许在名称中使用吗?在我看来,它会被解析为不同的标识符,由减号运算符分隔(尽管不确定它是如何编译的)
  • 如果不告诉我们有关这个神秘的other_vector4_type 的任何信息,您将不会得到消息灵通的答案。但到目前为止,earlz 的答案可能是最好的:编译器不保证结构大小。允许在它认为合适的地方添加填充。

标签: c++ struct unions


【解决方案1】:

C++ 编译器可以使该结构为 128 字节。 C++ 标准没有定义结构/联合的大小。但是,大多数编译器都有一个非标准的 __PACKED 属性,您可以将其添加到结构的声明中,它只会占用它需要的确切字节数

【讨论】:

  • 通常会有与包装相关的费用。您需要显式添加属性是有原因的。因此,只有在出于某种原因需要删除所有填充时才应该使用它(即,将其与某些内部内核结构对齐,或者在线传输上的数据包)。
【解决方案2】:

如果你的类中有虚函数,它会使你的对象比内部类型更大,因为 vtable 指针。

顺便说一句,“struct {”与说“class { public:”是一样的

【讨论】:

    【解决方案3】:

    我想您将为您的对象定义一个vtable 指针。要么是因为您启用了 RTTI,要么是任何虚拟方法(包括析构函数)都会添加 vtable

    http://en.wikipedia.org/wiki/Virtual_method_table

    通常,编译器为每个类创建一个单独的 vtable。当一个对象被创建时,一个指向这个 vtable 的指针,称为虚拟表指针或 vpointer,被添加为这个对象的一个​​隐藏成员(成为它的第一个成员,除非它成为最后一个 [2])。编译器还会在每个类的构造函数中生成“隐藏”代码,将其对象的vpointer初始化为对应vtable的地址。

    【讨论】:

      【解决方案4】:

      我刚刚编译

      #include <xmmintrin.h>
      #include <iostream>
      
      struct myType
      {
          union {
              float data[4];
              __v4sf v;
          };
          typedef union {
              float data[4];
              __v4sf v;
          } myType_internal_t;
      };
      
      int main() {
          std::cout << sizeof(myType) << std::endl;
          std::cout << sizeof(myType::myType_internal_t) << std::endl;
      }
      

      结果是:

      16
      16
      

      在 64 位架构上使用 gcc。正如预期的那样。 "__v4sf" 是一个由四个浮点数组成的向量类型。所以问题可能出在您的“other_vector_4_type”中。也许它是多态的和虚拟的,并且包含两个 vtable?你在“myType”中使用了更多的虚函数,从而进一步增加了它的大小? 该问题也可能与您的编译器或架构有关。

      【讨论】:

        猜你喜欢
        • 2015-11-30
        • 2015-09-29
        • 2019-08-12
        • 2021-11-01
        • 2012-09-30
        • 2018-11-13
        • 2021-09-20
        • 2022-07-06
        • 2017-06-30
        相关资源
        最近更新 更多