C++的struct类型的内存问题

本文通过实验展示了结构体中不同数据类型的内存分配情况,并深入探讨了内存对齐问题及其与操作系统分配内存单元大小的关系。进一步,通过添加多个char型数据,验证了内存对齐是否影响数据在结构体内的布局。

在用struct定义一个结构体的时候,突发想象:struct变量中的不同类型是怎么样分配内存的?

于是,用VC做了个小实验

struct中定义了char、int、float等类型数据

先来看看只有一个char类型数据,一个int类型数据,一个float类型数据,一个double类型数据的struct类型

struct Structure1 {
  char c1;
  int i;
  float f;
  double d;
};

#include <iostream>
using namespace std;

//typedef struct Structure1 struction;

int main() {
  
  struct Structure1 s1, s2;
  
  int size = sizeof s1;
  cout<<"Size of char is "<<sizeof(char)<<endl;
  cout<<"Size of int is "<<sizeof(int)<<endl;
  cout<<"Size of float is "<<sizeof(float)<<endl;
  cout<<"Size of double is "<<sizeof(double)<<endl;
  cout<<"Size of struct is "<<size<<endl;
  s1.c1 = 'a'; // Select an element using a '.'
  s1.i = 1;
  s1.f = 3.14;
  s1.d = 0.00093;
  cout<<"Size of struct is "<<size<<endl;
  cout<<"Address of s1 is "<<&s1<<endl;
  if((&s1) == (struct Structure1*)((void*)&(s1.c1)))
  {
	  cout<<"s1 share the same address with s1.c1!"<<endl;
  }
  else
  {
	  cout<<"s1 didn't share the same address with s1.c1!"<<endl;
  }
  cout<<"Address of s1.c1 is "<<&(s1.c1)<<endl;
  cout<<"Address of s1.i is "<<&(s1.i)<<endl;
  cout<<"Address of s1.f is "<<&(s1.f)<<endl;
  cout<<"Address of s1.d is "<<&(s1.d)<<endl;
  cout<<"Size of s1.d is "<<sizeof s1.d<<endl;
  cout<<"Size of s1.c1 is "<<sizeof s1.c1<<endl;
  s2.c1 = 'a';
  s2.i = 1;
  s2.f = 3.14;
  s2.d = 0.00093;
} 

运行结果



看到的是本来char型只有一个字节,但是从int地址和s1的起始地址来看,char型应该是占据了四个字节。这其实是一个内存对齐的问题,主要跟操作系统分配内存的单元大小有关。


所以下面,我就多添加几个char型

struct Structure1 {
  char c1;
  int i;
  float f;
  
  char c2;//让c2在定义的时候不跟在c1的后面,也就是想看看有没有内存对齐的问题
  char c3;
  char c4;
  double d;
};

#include <iostream>
using namespace std;

int main() {
  
  struct Structure1 s1, s2;
  
  int size = sizeof s1;
  cout<<"Size of char is "<<sizeof(char)<<endl;
  cout<<"Size of int is "<<sizeof(int)<<endl;
  cout<<"Size of float is "<<sizeof(float)<<endl;
  cout<<"Size of double is "<<sizeof(double)<<endl;
  cout<<"Size of struct is "<<size<<endl;
  s1.c1 = 'a'; // 
  s1.i = 1;
  s1.f = 3.14;
  s1.d = 0.00093;
  cout<<"Size of struct is "<<size<<endl;
  cout<<"Address of s1 is "<<&s1<<endl;
  if((&s1) == (struct Structure1*)((void*)&(s1.c1)))//判断有没有c1的地址是和struct变量的起始地址是一样的
  {
	  cout<<"s1 share the same address with s1.c1!"<<endl;
  }
  else
  {
	  cout<<"s1 didn't share the same address with s1.c1!"<<endl;
  }
  cout<<"Address of s1.c1 is "<<&(s1.c1)<<endl;
  cout<<"Address of s1.c2 is "<<&(s1.c2)<<endl;
  cout<<"Address of s1.c3 is "<<&(s1.c3)<<endl;
  cout<<"Address of s1.i is "<<&(s1.i)<<endl;
  cout<<"Address of s1.f is "<<&(s1.f)<<endl;
  cout<<"Address of s1.d is "<<&(s1.d)<<endl;
  cout<<"Size of s1.d is "<<sizeof s1.d<<endl;
  cout<<"Size of s1.c1 is "<<sizeof s1.c1<<endl;
  cout<<"Size of s1.c2 is "<<sizeof s1.c2<<endl;
  cout<<"Size of s1.c3 is "<<sizeof s1.c3<<endl;
} 
运行的结果如下:

可以看出虽然c2、c3并不是和c1在一起定义的,但是分配内存的时候还是没有另外分配四个字节,而是利用c1后面没有分配完字节给c2、c3


这里只是简单讨论了char型,当然大家还可以去思考其他诸如class等复杂的类型并验证

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值