C语言结构体占用内存深入讲解

前言

前几天有个小朋友问了我一下,关于C语言结构体占用空间的问题。觉得以后会对小可爱有点帮助,就打算先写一下。

struct Test
{
 int a;
 char b;
 int c;
} test;

理论上,结构体中的各个成员在内存中应该是连续储存的,就像数组里面的元素一样。事实上,也确实是这个样子的,不过和我们想象的有点不一样。

按照我们最初的想法,变量test所占的内存为 4 + 1 + 4 = 9。

但是我们写一个小代码验证一下发现和我们想的不一样。

它的内存为12。因为 int类型是4个字节,所以是不是各个成员的内存都是按照最大的那个设置呢?毕竟 4 * 3 = 12,我们再次实验,

如果按照我们的推测,那么内存大小应该是 8 * 3 = 24。为何是16呢?

下面我来总结一下。

总结

C语言结构体所占内存大小,其实里面涉及到C语言内存对齐,提高寻址效率的一种思想在里面。具体我就不在这里展开来说了,有兴趣的可以自己百度了解一下。

其实小可爱最想了解的应该是如何计算,结构体的内存大小。

不包含,数组和指针的结构体

对于不包含,数组和指针的结构体,知道各个成员所占内存大小后,可以直接相加,不过相加的时候必须保证前面的成员变量的内存所占内存必须是下一个成员变量所占内存的整倍数,如果不够就补上;并且最后的结果必须要是所占内存空间最大的成员变量的整倍数

下面我来几个例子说明:

struct Test
{
 double c; 	//8
 int a;		//4
 char b;		//1
} test;

所占内存大小,8 + 4 + 1 = 13,最大内存为8, 所以应该这样计算 8 + 4 + 4 = 16。
下面我们交换下,

struct Test
{
 int a;		//4
 double c; 	//8
 char b;		//1
} test;

所占内存大小, 4 + 8 + 1 = 13,因为double类型是8个字节,而前面只有4个字节,并且成员变量最大内存为8,所以应该这样计算 8 + 8 + 8 = 24。

struct Test
{
 int a;		//4
 char b;		//1
 double c; 	//8
} test;

同理4 + 1 + 8 = 13,应该变为 4 + 4 + 8 = 16。

包含,数组和指针的结构体 包含指针的结构体

对于包含指针的结构体,可以用和上面相同的方法进行计算,一般指针的大小都是固定的4个字节(在我的电脑上,你们可能不同),因为不管什么类型的指针只需要储存地址,不需要储存地址指向空间的内容。

struct Test
{
 char a;		//1
 char *b;	//4
 double c;	//8
} test;
struct Test
{
 char a;		//1
 int *b;	//4
 double c;	//8
} test;
struct Test
{
 char a;		//1
 double *b;	//4
 double c;	//8
} test;

这三种所占内存大小均为 4 + 4 + 8 = 16。如果将变量 b 和变量 c 的位置互换,则变为 8 + 8 + 8 = 24。 包含数组的结构体

数组中的元素地址是连续的,所以一个数组所占空间大小,为数组类型 * 元素个数。

知道了数组所占空间大小后,再来说说如何计算结构体中包含数组的情况,在之前计算的时候,我说过相加的时候必须保证前面的成员变量的内存所占内存必须是下一个成员变量所占内存的整倍数,但是如果下一变量为数组,则没有这个要求。

例如:

struct Test
{
 int a;
 char b[21];
 int d;
 double c;
} test;

应该为 4 + 24 + 4 + 8 = 40。

struct Test
{
 int a;
 char b[19];
 int d;
 double c;
} test;

应该为 4 + 20 + 8 + 8 = 40。

struct Test
{
 char a;		//1
 char b[19];	//19
 int d;		//4
 double c;	//8
} test;

应该为 1 + 19 + 4 + 8 = 32。

struct Test
{
 char a;		//1
 char b[17];	//17
 int d;		//4
 double c;	//8
} test;

应该为 1 + 19 + 4 + 8 = 32。

struct Test
{
 char a;		//1
 char b[15];	//15
 int d;		//4
 double c;	//8
} test;

应该为 1 + 15 + 8 + 8 = 32。

到此这篇关于C语言结构体占用内存的文章就介绍到这了,更多相关C语言结构体占用内存内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 详解C语言中的内存四区模型及结构体对内存的使用

    内存四区 1.代码区 代码区code,程序被操作系统加载到内存的时候,所有的可执行代码都加载到代码区,也叫代码段,这块内存是不可以在运行期间修改的. 2.静态区 所有的全局变量以及程序中的静态变量都存储到静态区. 3.栈区 栈stack是一种先进后出的内存结构,所有的自动变量,函数的形参都是由编译器自动放出栈中,当一个自动变量超出其作用域时,自动从栈中弹出.对于自动变量,什么时候入栈,什么时候出栈,是不需要程序控制的,由C语言编译器.实现栈不会很大,一般都是以K为单位的. 当栈空间以满,但还往栈

  • C语言结构体占用内存深入讲解

    前言 前几天有个小朋友问了我一下,关于C语言结构体占用空间的问题.觉得以后会对小可爱有点帮助,就打算先写一下. struct Test { int a; char b; int c; } test; 理论上,结构体中的各个成员在内存中应该是连续储存的,就像数组里面的元素一样.事实上,也确实是这个样子的,不过和我们想象的有点不一样. 按照我们最初的想法,变量test所占的内存为 4 + 1 + 4 = 9. 但是我们写一个小代码验证一下发现和我们想的不一样. 它的内存为12.因为 int类型是4个

  • C语言结构体计算内存占用问题解析

        c语言中结构体使用是非常广泛的,但是结构体有一个问题,就是如果开头的字段属性是字符类型(char),紧跟着的是其他类型,比如整型.长整型.双精度.浮点型,这时候结构体的大小会发生改变,下面给出一个示例: #include <stdio.h> struct person{ char sex; int age; char name[8]; }; int main() { printf("sizeof(person) = %d\n",sizeof(struct perso

  • C语言结构体中内存对齐的问题理解

    目录 前言 思考 结构体在内存中开辟空间时内存对齐的规则 为什么存在内存对齐 1.平台的原因 2.性能的原因 前言 学C的同学应该知道~ 想精通C语言就不得不面对—指针与内存 续上次指针的进阶,这一章我来聊一聊C语言内存对齐的问题 学习结构体的你有没有注意过结构体向系统申请的内存为多少呢的 思考 #include<stdio.h> typedef struct s1 { char a; char b; int c; }s1; typedef struct s2 { char a; int c;

  • C语言结构体(struct)的详细讲解

    目录 引言 1. 动态内存管理 2. 结构体 2.1 定义语法 2.2 定义示例 2.3 初始化 2.4 结构体赋值 2.5 结构体数组 2.6 结构体指针赋值 3. 学生管理系统 附:结构体变量的存储原理 总结 引言 当前文章介绍动态堆空间内存分配与释放,C语言结构体定义.初始化.赋值.结构体数组.结构体指针的相关知识点,最后通过一个学生管理系统综合练习结构体数组的使用. 1. 动态内存管理 C语言代码----->编译----->链接------>可执行的二进制文件(windows下x

  • C语言热门考点结构体与内存对齐详解

    目录 一.引例 1.结构体的第一个成员永远放在结构体起始位置偏移量为0的位置 2.从第二个成员开始,总是放在偏移量为一个对齐数的整数处,对齐数=编译器默认的对齐数和变量自身大小的较小值 3.结构体的总大小必须是各个成员的对齐数中最大的那个对齐数的整数倍 二.小试牛刀 三.嵌套结构体的特殊情况 四.关于为什么存在内存对齐 1.平台原因(移植原因): 2.性能原因: 总结 一.引例 到底什么是结构体内存对齐,我们用一段代码来介绍一下 struct S1 { char c1;//1字节 int a;/

  • C语言中结构体与内存对齐实例解析

    1.结构体类型 C语言中的2种类型:原生类型和自定义类型,结构体类型是一种自定义类型. 2.结构体使用时先定义结构体类型再用类型定义变量 -> 结构体定义时需要先定义结构体类型,然后再用类型来定义变量. -> 也可以在定义结构体类型的同时定义结构体变量. // 定义类型 struct people { char name[20]; int age; }; // 定义类型的同时定义变量. struct student { char name[20]; int age; }s1; // 将类型st

  • C语言中结构体的内存对齐规则讲解

    目录 1.结构体的内存对齐规则 2.例子 3.为什么存在内存对齐 4.如何修改默认对齐数 1.结构体的内存对齐规则 1.第一个成员在与结构体变量偏移量为0的地址处. 2.其他成员变量都放在对齐数(成员的大小和默认对齐数的较小值)的整数倍的地址处. 对齐数=编译器默认的一个对齐数与该成员大小的较小值.(VS中默认的对齐数是8) 3.结构体总大小为最大对齐数(每个成员变量都有一个对齐数 )的整数倍. 4.如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最

  • C语言结构体超详细讲解

    目录 前言 1.结构体的声明 1.1 结构的基础知识 1.2 结构的声明 1.3 结构成员的类型 1.4 结构体变量的定义和初始化 2.结构体成员的访问 2.1 点操作符访问 2.2 ->操作符访问 3.结构体传参 3.1 参数是结构体类型的变量 3.2 参数是结构体类型的变量的地址 3.3 结构体传参对比 总结 前言 本文开始学习结构体的知识点,主要内容包括: 结构体类型的声明 结构体初始化 结构体成员访问 结构体传参 1.结构体的声明 1.1 结构的基础知识 结构是一些值的集合,这些值称为成

  • C语言结构体简单入门讲解

    结构体 定义:用于存储不同的数据类型,存储在同一块内存空间里面 关键字 struct 标签 结构体名称 成员 例如: struct student { char name[20]: char sex; int age; float grade; }: 结构体后面不要忘记加分号 结构体至少需要一个标签,证明身份 结构体的使用 .访问指针 →访问 #include <stdio.h> #include <string.h> struct student { char name[20];

随机推荐