struct结构体内存大小

一. 基本原则

1. struct中成员变量的声明顺序,与成员变量对应的内存顺序是一致的;

2. struct本身的起始存储地址必须是成员变量中最长的数据类型的整倍数,注意是最长的数据类型,而不是最长的变量

3. 内存对齐与编译器设置有关。

二. 计算规则(以下的所有规则,必须同时满足,并不是满足其中一条即可)

1. 每个成员变量相对于struct起始地址的偏移量,必须是成员变量自身类型长度的最小整倍数

int number;是声明的第一个成员变量,相对于S001起始地址的偏移量为0

double tmp; 是声明的第二个成员变量,类型double长度8,根据规则1偏移量必须是8的最小倍数,当前偏移量是4,需要补充4个字节,则偏移量为8

2. 结构体内存大小,必须是成员变量中类型长度最长者的整倍数,如果不是,则在最后一个成员变量后补齐

根据1,int number和double tmp在内存中样式如下:

char c;是声明的第三个成员变量,类型char 1字节,偏移量为16

现在内存是17个字节,结构体S002中成员变量double tmp类型最长8个字节,17不能整除8,能整除8的最小数是24,则在char c后填补7个字节到24个字节

3. 成员变量是数组时,按照类型长度对齐,而不是数组长度对齐

int number;是声明的第一个成员变量,相对于S001起始地址的偏移量为0

char c[10];是声明的第二个成员变量,类型char 1字节,数组长度10,注意是按照类型char 1字节计算偏移量,偏移量4

double tmp; 是声明的第三个成员变量,类型double长度8,根据规则1偏移量必须是8的最小倍数,当前偏移量是14,需要补充2个字节,则偏移量为16

一共24字节,是最大类型double长度8的整倍数

4. 成员变量是结构体时,根据struct基本原则,其存储偏移量必须是成员变量中最长的数据类型的整倍数(当进行规则2的判断时,结构体变量也是使用成员变量中最长类型,结合上边几条规则,这个其实很好理解的)

这里运行3组数据进行验证:

  4-1> 如下图所示,结构体S004中结构体成员变量 S041 s41,结构体S041中成员变量的类型最长是1,因此s41的偏移量为14

  4-2> 下图为另一组结果图, 结构体S004中结构体成员变量 S041 s41,结构体S041中成员变量的类型最长是int 4,S004.c[10]的偏移量为4,长度为10,即结束位置是14,14不能整除4,因此S004.s41的偏移量补齐到16

  4-3> 下图中结构体S041中成员变量的类型最长是int 4,S004.c[10]偏移量为16,长度10,即结束位置为26,26不能整除4,所以补齐到28

5. 成员变量是联合体时,union的基本原则与struct一样,其存储偏移量必须是成员变量中最长的数据类型的整倍数,并且当进行规则2的判断时,联合体变量也是使用成员变量中最长类型(关于union的基本介绍,请看这里http://www.cnblogs.com/xieyajie/p/8086861.html

时间: 2024-10-10 13:10:35

struct结构体内存大小的相关文章

C struct结构体内存对齐问题

在空间看到别人的疑问引起了我的兴趣,刚好是我感兴趣的话题,就写一下.为了别人的疑问,也发表在qq空间里.因为下班比较晚,10点才到家,发表的也晚.其实是个简单的问题.  直接用实例和内存图说明: #include <iostream> using std::cout; using std::cin; struct stu { char sex; int length; char name[10]; }; void main() { stu stu0; stu0.sex = 'f'; stu0.

【APUE】Chapter17 Advanced IPC &amp; sign extension &amp; 结构体内存对齐

17.1 Introduction 这一章主要讲了UNIX Domain Sockets这样的进程间通讯方式,并列举了具体的几个例子. 17.2 UNIX Domain Sockets 这是一种特殊socket类型,主要用于高效的IPC,特点主要在于高效(因为省去了很多与数据无关的格式的要求). int socketpair(int domain, int type, int protocol, int sockfd[2]) 这个函数用于构建一对unix domain sockets:并且与之前

C++ Primer 学习笔记_15_从C到C++(1)--bool类型、const限定符、const与#define、结构体内存对齐

欢迎大家阅读参考,如有错误或疑问请留言纠正,谢谢 一.bool类型(C语言没有) 1.逻辑型也称布尔型,其取值为true(逻辑真)和false(逻辑假),存储字节数在不同编译系统中可能有所不同,VC++中为1个字节. 2.声明方式:bool result; result=true; 3.可以当作整数用(true一般为1,false为0) 4.把其它类型的值转换为布尔值时,非零值转换为true,零值转换为false 5.示例 #include <iostream> using namespace

结构体内存对齐规则

结构体内存对齐规则 1.第一个成员在与结构体变量偏移量为0的地址处: 2.其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处: 对齐数=编译器默认的对齐数 与 该成员大小的较小值: vc中默认为对齐数为8 linux中默认对齐数为4 3.结构体总大小为最大对齐数的整数倍: 4.如果嵌套了结构体,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体 的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍 如下面代码 struct A { int a;//4  8   ->4 char c

关于结构体内存对齐方式的总结(#pragma pack()和alignas())

最近闲来无事,翻阅msdn,在预编译指令中,翻阅到#pragma pack这个预处理指令,这个预处理指令为结构体内存对齐指令,偶然发现还有另外的内存对齐指令aligns(C++11),__declspec(align(#))(Microsoft专用),遂去探究两者之间的不同点. 1.#pragma pack 这个指令为预处理指令,所谓与处理指令执行在程序的预处理阶段,该指令对应着编译选项/Zp,可以在vs的工程属性中设置编译选项的内存对齐,也可以利用预处理指令来设置. #pragma pack(

结构体内存对齐——

什么是内存对齐 编译器为每个“数据单元”安排在某个合适的位置上: C,C++语言非常灵活,它允许你干涉“内存对齐” 为什么要对齐 性能原因:在对齐的地址上访问数据快 如何对齐 第一个数据成员放在offset为0的位置 其它成员对齐至min(sizeof(member),#pragma pack()所指定的值)的整数倍. 整个结构体也要对齐,结构体的总大小对齐至各个成员中最大对齐数的整数倍. #include<iostream> #include <stdio.h> using na

关于结构体内存对齐

对齐规则如下: 1.  结构体的大小等于结构体内最大成员大小的整数倍2.  结构体内的成员的首地址相对于结构体首地址的偏移量是其类型大小的整数倍,比如说double型成员相对于结构体的首地址的地址偏移量应该是8的倍数.3.  为了满足规则1和2编译器会在结构体成员之后进行字节填充! 注: 1. 内存对齐只是一种用空间来换时间的方法. 2. 实际上不同的编译器他的优化规则并不完全相同.

结构体内存对齐的原则及原理

结构体是C语言的一大特色,今天就来思考两个问题. 它的成员的顺序排列有什么要求吗? 原则一:结构的首变量地址偏移量offset为0,之后每个变量的首地址都要是其本身宽度的整数倍.总size=(0+1)+(3+4)+(0+8)=16. 原则二:结构体的大小一定是最大成员宽度的整数倍,依照原则1,总size=8+4+1=13:因为原则二,所以要在char后补齐3位,总size=16. 2.为什么要设计内存对齐这种方式? 当cpu需要取4个连续的字节时,若内存起始位置的地址可以被4整除,那么我们称其对

浅谈C/C++结构体内存分配问题

.wiz-todo, .wiz-todo-img {width: 16px; height: 16px; cursor: default; padding: 0 10px 0 2px; vertical-align: -10%;-webkit-user-select: none;} .wiz-todo-label { display: inline-block; padding-top: 7px; padding-bottom: 6px; line-height: 1.5;} .wiz-todo