C语言结构体在内存中的存储情况探究------内存对齐



条件(先看一下各个基本类型都占几个字节):

void size_(){
    printf("char类型:%d\n", sizeof(char));
    printf("int类型:%d\n", sizeof(int));
    printf("float类型:%d\n", sizeof(float));
    printf("double类型:%d\n", sizeof(double));
    return;
}

结果:



先来一下, 这个结构体在内存中占有多少个字节的内存呢?

typedef struct mystruct{  /*结构1*/
    int i_int;
    char c_char;
    char s_char[9];
}MYSTRUCT;

这个呢(交换数据成员顺序)?

typedef struct mystruct{   /*结构体2*/
    char c_char;
    int i_int;
    char s_char[9];
}MYSTRUCT;


现在让它自己告诉我们

int main()
{
    MYSTRUCT my_st = {0};
    int size_struct = sizeof(my_st);
    printf("%d\n", (int)&my_st.i_int);
    printf("%d\n", (int)&my_st.c_char);
    printf("%d\n", (int)my_st.s_char);
    printf("占用内存大小:%d 个字节\n", size_struct);

    return 0;
}

首先看结构体1的结果

可以看出:int占有4个字节, char占有了1个字节, 那么后面char类型的数组占有了11个字节

这是什么鬼?明明定义了char数组长度为9为什么会是11

别着急继续向下看

查看结构体2的结果(难道不是16?)

哈哈, 竟然又出来个20



揭晓答案

这是因为结构体的存储存在内存对齐机制,也就是  < 结构体大小能被最宽基本类型成员大小所整除 >

基本类型指的是 char  int  double 等,这样的对齐机制使得寻址更加方便



为什么结构体1占有16个字节

因为单个char成员会与其下面的char类型数组组合在一起  也就是相当于一个char类型的长度为10的数组

其中最宽基本类型为 int  占4个字节  而后面的 ”char[10]“数组要满足是int占有4个字节的整数倍最小的就是12, 所以共16个字节



为什么结构体2占有20个字节

第一个成员为char单个字符, 其后面是一个int类型,不能结合故要给char分配4个字节

后面的char数组当然还要分配12个字节, 所以4+4+12=20个字节



了解了对齐机制后再来分析一个

typedef struct mystruct{   /*结构体3*/
    char c_char;
    double d_double;
    int i_int;
    char s_char[9];
}MYSTRUCT;

分析

最宽基本类型是 double 占有8个字节----------------------------------------------------------------8

第一个char占有1个, 但是要补齐为8个字节---------------------------------------------------------8

后面的int占有4个,相当于4个char类型,与char数组结合为 ”char[4+9]“ , 要补齐为16个字节----16

得到结果-------------------------------------------------------------------------------------------32

验证一下

果然就是这样



本节完......

原文地址:https://www.cnblogs.com/xinglichao/p/9189922.html

时间: 2024-10-07 22:19:26

C语言结构体在内存中的存储情况探究------内存对齐的相关文章

C语言 结构体的内存对齐问题与位域

http://blog.csdn.net/xing_hao/article/details/6678048 一.内存对齐 许多计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的首地址的值是某个数k(通常它为4或8)的倍数,这就是所谓的内存对 齐,而这个k则被称为该数据类型的对齐模数(alignment modulus).当一种类型S的对齐模数与另一种类型T的对齐模数的比值是大于1的整数,我们就称类型S的对齐要求比T强(严格),而称T比S弱(宽 松).这种强制的要求一来简化了处

解析C语言结构体对齐(内存对齐问题)

C语言结构体对齐也是老生常谈的话题了.基本上是面试题的必考题.内容虽然很基础,但一不小心就会弄错.写出一个struct,然后sizeof,你会不会经常对结果感到奇怪?sizeof的结果往往都比你声明的变量总长度要大,这是怎么回事呢? 开始学的时候,也被此类问题困扰很久.其实相关的文章很多,感觉说清楚的不多.结构体到底怎样对齐? 有人给对齐原则做过总结,具体在哪里看到现在已记不起来,这里引用一下前人的经验(在没有#pragma pack宏的情况下): 原则1.数据成员对齐规则:结构(struct或

c语言结构体中动态数组的使用

[背景] c语言结构体中动态数组使得用户能够根据需要来申请空间,相比静态数组,更能有效利用存储空间. [正文] 1. 动态数组在结构体中间 #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct { int a; char buf[0]; // 或者char buf[]; int b; }Node; int main() { printf("%d\n", si

逆向知识第十四讲,(C语言完结)结构体在汇编中的表现形式

一丶了解什么是结构体,以及计算结构体成员的对其值以及总大小(类也是这样算) 结构体的特性 1.结构体(struct)是由一系列具有相同类型或不同类型的数据构成的数据集合 2.在C语言中,结构体(struct)指的是一种数据结构,是C语言中聚合数据类型(aggregate data type)的一类. 3. 结构体可以被声明为变量.指针或数组等,用以实现较复杂的数据结构.结构体同时也是一些元素的集合,这些元素称为结构体的成员(member),且这些成员可以为不同的类型,成员一般用名字访问. 高级代

结构体在内存中的存储方式

结构体在内存中如何存储? 遵循结构体对齐规则: 1.首先要知道默认对齐数:VS 中 8   Linux 中4 2.第一个成员放到0偏移处 3.后面所有的成员都放到对齐数(本身和默认对齐数的较小值)的倍数处偏移 4.结构体总大小为所有对齐数中最大对齐数的倍数 Eg: 运行结果为 24 图中可以看出内存有浪费,而我们将小的成员放一起可以节省资源 减少浪费. 上例可以改为: int i: char c: double d: 这样总大小只需16 节省浪费. 空的结构体类型大小为1,创建对象需要开辟空间,

C语言结构体声明中冒号的使用(占位符) &amp; C结构体的乱序初始化

有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位.例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可.为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为"位域"或"位段".所谓"位域"是把一个字节中的二进位划分为几 个不同的区域,并说明每个区域的位数.每个域有一个域名,允许在程序中按域名进行操作.这样就可以把几个不同的对象用一个字节的二进制位域来表示.一.位 域的定义和位域变量的说明位域定义与

在C语言结构体中添加成员函数

我们在使用C语言的结构体时,经常都是只定义几个成员变量,而学过面向对象的人应该知道,我们定义类时,不只是定义了成员变量,还定义了成员方法,而类的结构和结构体非常的相似,所以,为什么不想想如何在C语言结构体中添加成员变量呢 在C语言的结构体中是不能直接定义成员函数的,这点和C++不同,但是我们可以通过定义一个函数指针的方式来指向一个方法. 示例代码如下: 1 #include<stdio.h> 2 #include<stdlib.h> 3 typedef struct node 4

C语言——结构体数组的使用案例(如何判断两个矩形是否相交,其中一个是否包含在另外一个里面,点是否在矩形中)

Rect.h struct CPoint { float x; float y; }; typedef struct CPoint CPoint; struct CSize { float width; float height; }; typedef struct CSize CSize; struct CRect { CPoint origin; CSize size; }; typedef struct CRect CRect; //判断两个矩形是否相交 BOOL isIntersecti

C语言结构体,C语言结构体指针,java对象引用,传值,传地址,传引用

C语言结构体,C语言结构体指针,java对象引用,传值,传地址,传引用 传值 把实参的值赋值给行参 那么对行参的修改,不会影响实参的值 传地址 传值的一种特殊方式,只是他传递的是地址,不是普通的如int 那么传地址以后,实参和行参都指向同一个对象 传引用 真正的以地址的方式传递参数 传递以后,行参和实参都是同一个对象,只是他们名字不同而已 对行参的修改将影响实参的值 所谓变量是内存地址的一个抽象名字,在静态编译的程序中,所有变量名都会在编译时转换成内存地址,机器不知道变量名,只知道地址. C 语