C类的大小如何确定?

前端之家收集整理的这篇文章主要介绍了C类的大小如何确定?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
总结:编译器如何在编译期间静态确定C类的大小?

细节:

我想知道什么规则用于确定一个类将使用多少内存,以及内存如何对齐.

例如,以下代码声明了4个类.前2个都是16个字节.但是3是48字节,即使它包含与前2个相同的数据成员.而第四个类与第三个数据成员具有相同的数据成员,只有不同的顺序,但它是32个字节.

#include <xmmintrin.h>
#include <stdio.h>

class TestClass1 {
  __m128i vect;
};

class TestClass2 {
  char buf[8];
  char buf2[8];
};

class TestClass3 {
  char buf[8];
  __m128i vect;
  char buf2[8];
};

class TestClass4 {
  char buf[8];
  char buf2[8];
  __m128i vect;
};


TestClass1 *ptr1;
TestClass2 *ptr2;
TestClass3 *ptr3;
TestClass4 *ptr4;
int main() {
  ptr1 = new TestClass1();
  ptr2 = new TestClass2();
  ptr3 = new TestClass3();
  ptr4 = new TestClass4();
  printf("sizeof TestClass1 is: %lu\t TestClass2 is: %lu\t TestClass3 is: %lu\t TestClass4 is: %lu\n",sizeof(*ptr1),sizeof(*ptr2),sizeof(*ptr3),sizeof(*ptr4));
  return 0;
}

我知道答案与课程数据成员的对齐有关.但是我正在试图明白这些规则是什么,以及在编译步骤中如何应用这些规则,因为我有一个类具有__m128i数据成员,但是数据成员不是16字节对齐,这导致了一个segfault,当编译器使用movaps生成代码来访问数据.

解决方法

对于POD(普通旧数据),规则通常为:

>结构中的每个成员有一些大小和一些对齐要求a.@H_502_17@>编译器以大小S设置为零并将对齐要求A设置为一(字节)开始.@H_502_17@>编译器按顺序处理结构中的每个成员:

考虑会员的对齐要求a.如果S当前不是a的倍数,则只添加足够的字节S,以便它是a的倍数.这决定了会员将去哪里;它将从结构的开头(对于S的当前值)到偏移量S.@H_502_17@>将A设置为A和a的最小公倍数.@H_502_17@>将s添加到S,为会员留出空间.

>当对每个成员进行上述过程时,请考虑结构的对齐要求A.如果S当前不是A的倍数,则只需将其添加到S中,使其为A的倍数.

上述结构的大小是S的值.

另外:

>如果任何成员是数组,它的大小是元素的数量乘以每个元素的大小,其对齐要求是元素的对齐要求.@H_502_17@>如果任何一个成员是一个结构,其大小和对齐要求如上所述计算.@H_502_17@>如果任何成员是一个联盟:

>将S设置为最大成员的大小.@H_502_17@>将A设置为所有成员对齐的最小公倍数.@H_502_17@>如果S不是A的倍数,只需加上S,使其成为A的倍数.

考虑你的TestClass3:

> S从0开始,A从1开始.@H_502_17@> char buf [8]需要8个字节和对齐1,所以S增加8到8,A保持1.@H_502_17@> __m128i vect需要16个字节和对齐16.首先,S必须增加到16以给出正确的对齐.那么A必须增加到16.然后S必须增加16以为vect空间,所以S现在是32.@H_502_17@> char buf2 [8]需要8个字节和对齐1,所以S增加8到24,A保持16.@H_502_17@>最后,S是24,这不是A(16)的倍数,所以S必须增加8到32.

所以TestClass3的大小是32字节.

对于基本类型(int,double等),对齐要求取决于实现,主要由硬件决定.在许多处理器上,当数据具有一定的对齐方式(通常在内存中的地址是其大小的倍数)时,加载和存储数据的速度更快.除此之外,上述规则大部分来自逻辑;他们将每个成员放在必须满足对齐要求的地方,而不需要占用更多的空间.

猜你在找的C&C++相关文章