C语言结构体所占内存大小

用一道面试题题引入
struct str1    
{    
     char   a;    
     int    b;    
     float  c;
     double d;  
};
char类型占用1个字节,int型占用4个字节,short类型占用2个字节,float占4字节,double占8字节;
那么我们可能会犯一个错误就是直接1+4+2=7,认为该结构体占用7个字节。这是错的。
百度一了下发现这是因为计算机中存在一种叫做内存对齐的机制导致了该结果的发生。

在计算机中通常会让CPU从内存中一次读取若干个字节的数据,而不是一次只读取一个字节的数据,这样的好处是提高了计算机的效率,然而坏处也显而易见。
假设CPU要从内存中寻找一个char型的数据和一个int型的数据,如果内存不对齐,当一次读取四个字节时,CPU找到了char型的数据后再跨越四个字节,而此时CPU的指向到了int型的中间区域,导致这个int型变量未找到,然后CPU会返回去再次寻找,直到找到该int型变量。这样不但没能提高效率,反而增加了CPU的负担。因此我们通常会在第一个char型变量后边填充一部分数据来保证每次寻址时地址都是该数据的整数倍,这样就避免了上述“错误”的发生,也就是所谓的内存对齐。

于是,我通过查阅资料总结了内存对齐的以下两个规则:
1.起始位置为该数据类型所占内存的整数倍,若不足则将不足部分填充,使其变为该数据类型所占内存的整数倍。
2.结构体所占总内存为其成员变量中所占空间最大数据类型的整数倍。
(对于32位操作系统下各数据类型的所占内存大小可以参考这篇文章:C语言数据类型与内存映射图)

假设上题中结构体变量是从0号内存开始存储,用一个字节存储了字符变量a;然后需要存储整形变量b,这时不能直接存储,因为对于b的起始位置不满足为它的数据类型所占内存的整数倍,所以应将接下来的1,2,3号内存填充占位,然后再用四个字节存储b。接下来可以直接存储float变量c,这时已经使用了1+3+4+4=12个字节内存地址。接下来存储double类型的d时,我们知道double类型需要占8字节的内存,12不是8的倍数,无法完成内存对齐,需要补充4个字节内存占位,然后再存储d,这样我们就可以计算出该结构体所占内存为12+4+8=24字节。
 存储形式如下图:

char   a
 
 
 
int   b
b
b
b
float   c
c
c
c
 
 
 
 
double  b
b
b
b
b
b
b
b

原文地址:https://www.cnblogs.com/wxylyw/p/9077885.html

时间: 2024-08-01 04:27:17

C语言结构体所占内存大小的相关文章

结构体所占内存大小

结构体所占内存大小划分原则: 1.划分字节,按照当前结构体中,字节数最大的类型作为划分单元.[这里面还有一些前提.下面的例子会详细说到] 2.以矩形块儿的形式划分. #include <stdio.h> /**划分示意图: 最小单元是 double所以 这个 地方按照8个字节作为最小单元来划分. */ struct student1 { double avgMark; int ID; }; /**划分示意图: 最小单元不能是数组这个地方的最小单元是 1个字节 */ struct student

结构体所占字节大小计算以及共用体大小计算

#include<stdio.h> struct student{ int num; char sex; float score; } ; union data{ int k; char ch; float f; }; int main(void){ printf("%d\n",sizeof(struct student)); printf("%d",sizeof(union data)); } 详细计算见:https://blog.csdn.net/u

iOSDay06C语言结构体

1.结构体的概述 在C语言中,结构体(struct)指的是一种数据结构,是C语言中构造类型的其中之一. 在实际应用中,我们通常需要由不同类型的数据来构成一个整体,比如学生这个整体可以由姓名.年龄.身高等数据构成,这些数据都具有不同的类型,姓名可以是字符串类型,年龄可以是整型,身高可以是浮点型. C语言便提供了结构体来解决我们的这种需求,它允许内部的元素是不同类型的. 结构体是用来存放相同类型数据或者不同类型数据的自定义数据类型 2.结构体的定义 struct 结构体名 {      成员变量1;

C语言结构体占用空间内存大小解析

结构体的数据类型的有点我们就不啰嗦了,直接来看相同数据结构体的几种书写的格式吧. 格式一: [cpp] view plain copy 01.struct tagPhone 02.{ 03.     char   A; 04.     int    B; 05.     short  C; 06.}Phone; [cpp] view plain copy 格式二: [cpp] view plain copy 01.struct tagPhone 02.{ 03.     char   A; 04

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

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

【C语言】结构体中的内存对齐问题

话说大家有没有发现结构体中的内存对齐问题很有意思呢?我们这一次就一起研究一下这个问题为什么值得人探讨. 结构体内存对齐有三个原则; 1.数据成员对齐规则:结构(struct或联合union)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储). 2.结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储.(struct a里存有s

C语言结构体(struct)常见使用方法(转)

本文转自 CSDN huqinweI987 基本定义:结构体,通俗讲就像是打包封装,把一些有共同特征(比如同属于某一类事物的属性,往往是某种业务相关属性的聚合)的变量封装在内部,通过一定方法访问修改内部变量. 结构体定义: 第一种:只有结构体定义 [cpp] view plaincopy struct stuff{ char job[20]; int age; float height; }; 第二种:附加该结构体类型的“结构体变量”的初始化的结构体定义 [cpp] view plaincopy

读陈浩的《C语言结构体里的成员数组和指针》总结,零长度数组

原文链接:C语言结构体里的成员数组和指针 复制如下: 单看这文章的标题,你可能会觉得好像没什么意思.你先别下这个结论,相信这篇文章会对你理解C语言有帮助.这篇文章产生的背景是在微博上,看到@Laruence同学出了一个关于C语言的题,微博链接.微博截图如下.我觉得好多人对这段代码的理解还不够深入,所以写下了这篇文章. 为了方便你把代码copy过去编译和调试,我把代码列在下面: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include <stdio.h>

不可或缺 Windows Native (8) - C 语言: 结构体,共用体,枚举,类型定义符

[源码下载] 作者:webabcd 介绍不可或缺 Windows Native 之 C 语言 结构体 共用体 枚举 类型定义符 示例cStruct.h #ifndef _MYHEAD_STRUCT_ #define _MYHEAD_STRUCT_ #ifdef __cplusplus extern "C" #endif char *demo_cStruct(); #endif cStruct.c /* * 结构体,共用体,枚举,类型定义符 * * 注:结构体变量在做参数传递时,其内每个