[C++][基础概念](一)结构体所占内存大小的判断

以下内容是在做牛客网的选择题遇到的困惑和总结,其中主要是引用的别人的博客或者答案,和加入了自己的一些总结,方便以后翻过来看时更加有条理。

一、理论说明

 一个结构体变量定义完之后,其在内存中的存储并不等于其所包含元素的宽度之和。

1.有两个原则:

原则一:结构体中元素是按照定义顺序一个一个放到内存中去的,但并不是紧密排列的。从结构体存储的首地址开始,每一个元素放置到内存中时,它都会认为内存是以它自己的大小来划分的,因此元素放置的位置一定会在自己宽度的整数倍上开始(以结构体变量首地址为0计算)

原则二:在经过第一原则分析后,检查计算出(最后所需)的存储单元是否为所有元素中最宽的元素的长度的整数倍,是,则结束;若不是,则补齐为它的整数倍

2.包含指针的情况:

只要记住指针本身所占的存储空间是4个字节就行了,而不必看它是指向什么类型的指针。

3.有关 #pragma pack(n)

参考:http://blog.csdn.net/mylinx/article/details/7007309

4.有关union:

取决于它所有成员中,占用空间最大的成员的大小,并且需要内存对齐

二、一些例子 

1.  

struct X

 {

char a;

int b;

double c;

 } S1;

分析:a:1, b:4,c:8 1+(3)+4+8=16

 struct X

 {

char a;

double b;

int c;

} S2;

分析: 1+(7)+8+4+(4:补充到最宽元素长度的倍数)=24

 struct X

{

double a;

char b;

int c;     

}S3;

分析:8+1+3+4=16

struct X

 { 

double a;

char b;

int c;

char d;   

 } S4;

8+1+(3)+4+1+()=24

2.

已知int占量字节,char占1个字节,float占4个字节,求sizeof(xc)

struct stu

{

union{

char bj[5];

int bn[2];

}class;

char xm[8];

float cj;

}xc;

注意 bj[5]是储存了5个char类型的数组,不要认为是指针,还有联合体选择最大的那个

5*1+(3)+8+4=20

3.

#pragma pack(2)

class BU

{

int number;

union UBffer

{

char buffer[13];

int number;

}ubuf;

void foo(){}

typedef char*(*f)(void*);

enum {hdd,ssd,blueray}sk;

}bu;

union 取决于它所有的成员中,占用空间最大的成员大小,并且需要内存对齐。

又因为有#pragma pack(2),对齐的字节数为2,union的大小为14

void foo()不占字节

typedef char*(*f) (void*);不占

enum {hdd, ssd, blueray}disk;4个字节

故总共有22个字节。

4. void Func( char str[100]){} 中 sizeof(str)是多少?

数组作为参数时,[]中的数不起作用,传递的是首元素的地址,故为4个字节

5.在x86系统下,sizeof如下结构体的值是多少?

struct{

char a[10];

int b;

short c[3];

}

答案为24,char a[10]并不代表结构体需要对齐的长度为10,它只是10个char聚在一起,本质没有变化,所以对齐长度是10,

故 4(char a[4])+4(char a[4])+4(char a[2],内存对齐)+4(int)+4(short[2])+4(short[1],内存对齐)

6.

typedef struct list_t{

struct list_t *next;

struct list_t *prev;

char data[0];

}list_t;

sizeof(list_t)是8byte

柔性数组(参考http://blog.csdn.net/yby4769250/article/details/7294696):直观上来看就是0长数组

StructPacket

{

Int state;

Int len;

CharcData[0]; //这里的0长结构体就为变长结构体提供了非常好的支持

};

 

用途:长度为0的数组主要是为了满足需要变长度的结构体

用法:在一个结构体的最后,申明一个长度为0的数组,就可以使得这个结构体是可变长度的,对于编译器而言,该长度为0的数组并不占用空间,因为数组名本身不占用空间。


三、参考资料:

结构在内存中的对齐规则: http://blog.csdn.net/liukun321/article/details/6974282

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值