21xrx.com
2024-09-17 03:47:49 Tuesday
登录
文章检索 我的文章 写文章
针对C++中struct的大小进行详解
2023-07-12 02:18:48 深夜i     --     --
C++ struct 大小 成员对齐 内存空间

C++中,struct是一种特殊类型,它类似于一个类,但其成员变量默认为公有的。当我们定义一个struct时,我们可能会感到困惑:它会占用多少存储空间?这是因为C++中的struct的大小并不总是显而易见的。

首先,让我们看一下一个简单的struct定义:


struct Person {

  char name[20];

  int age;

  float height;

};

Person包含3个成员变量:name、age和height。那么这个struct的大小是多少呢?我们可以通过使用sizeof关键字来获取一个对象(这里指Person)的大小:

sizeof(Person)

我们可能会认为这个struct的大小是20+4+4=28字节(根据我们的定义,name是一个长度为20的字符数组,int是4个字节,float也是4个字节)。但事实并非如此。

C++编译器可以以摆放顺序的方式优化struct的大小,以便尽可能少地使用字节。因此,该struct的大小可能会更少。实际上,我们可以使用下面的代码来测试:


struct Person {

  char name[20];

  int age;

  float height;

};

int main() {

  Person p;

  std::cout << sizeof(p) << std::endl;

  return 0;

}

在64位系统上,上面的代码输出结果是24字节。在32位系统上,这个数值可能会是16个字节,这取决于编译器和操作系统的不同。

如何计算struct大小?

在C++中,要计算一个struct的大小,我们需要知道以下几点:

1. 每个成员变量所占用的字节数

如前所述,不同类型的变量将占用不同数量的字节。以下是几个基本数据类型所占用的字节数:


char:1个字节

bool:1个字节

short:2个字节

int:4个字节

float:4个字节

double:8个字节

此外,对于数组类型的成员变量,我们可以使用它的大小乘以数组的长度来计算所占用的总字节数。

2. 内存对齐

C++编译器有时会在内存中为变量进行对齐。这是为了确保结构体中的每个成员变量都从与结构体初始地址的某个字节的整数倍开始。默认情况下,对齐方式为8字节。这意味着结构体中的每个成员变量都应该是8的倍数。

例如,在结构体中定义了一个float类型的成员变量,C++编译器会将其放置在下一个8字节的边界上。考虑以下结构体定义:


struct MyStruct

  char a;     //1个字节

  float b;    //4个字节

  double c;    //8个字节

  long long d;  //8个字节

;

该结构体的大小是什么?对于char类型的成员变量,只占用一个字节。但是,C++编译器大概率会在它周围添加一些空间,以免下一个成员变量的开始地址不是8的倍数。在这个例子中,float类型的成员变量需要放置到8的倍数上。因此,总字节数为:


1(a)+ 3(对齐空间)+ 4(b)+ 4(对齐空间)+ 8(c)+ 8(d)= 28

如何避免尺寸问题?

在大多数情况下,C++编译器会自动为您优化结构体的大小。但是,如果您需要确保准确的大小,您可以使用pragma pack指令。


#pragma pack(1)

struct MyStruct

  char a;     //1个字节

  float b;    //4个字节

  double c;    //8个字节

  long long d;  //8个字节

;

#pragma pack()

这将告诉编译器不要使用对齐方式,而是按照变量大小填充字节,从而得到总的结构体大小。

由此可以看出,C++结构体的大小计算并非易如反掌。编译器在处理结构体的构成时,会对变量进行对齐操作,将其按照一定的字节间隔配置在内存中。因此我们不必纠结于结构体的大小,在实际问题中仍旧可以寻求合适的解决方式。

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复