问题描述
问题一:今天在学习数据结构——链表
的过程中,突然想搞明白一下,简单链表,它一个结点占据多大内存啊。
1 | typedef struct linkednode |
问题二:另外,还有菜鸡的我心中一直有一个疑问,头指针head
,它占据多大内存啊,是和一个结点一样大的内存吗?还是只是一个指针所占据的内存大小啊。
结论
首先问题一,结点用的是结构体定义,结构体所占据内存的计算,要满足一个内存对齐原理,所以计算结点所占据的内存,要在对齐原理的前提下,进行计算。我的系统是
64位
的,用的编译器是Dev C++
,我一个结点占据的内存是16字节
。然后问题二,头指针head,是一个指针变量,所有的指针变量在我这里,占据的内存都是
8字节
,不是和结点一样大的内存。它只是一个指针变量,这个变量head指向一个内存占16字节的结点。
1 | typedef struct linkednode //16字节 |
分析
背景
运行环境
操作系统为win10 64位
,编译器是Dev C++
内存对齐原理
这是因为为了CPU能够快速的访问,提高访问效率,变量的起始地址应该具有某些特性,这就是所谓的“对齐”。比如这里4字节
的int型
变量,那他的起始地址应该在4字节的边界上,即起始地址可以被4整除。
内存对齐的规则:
- 起始地址为该变量的类型所占的整数倍,若不足则不足部分用数据填充至所占内存的整数倍。
- 该结构体所占内存为结构体成员变量中最大数据类型的整数倍。
因此上面的结构体中int data
占4字节
,而*next
这个指针变量占8字节
,现在共占12字节
,但由于内存对齐原理,因为起始字节要为*next 八字节
的整数倍,因此从8字节
算起,现在共16字节
,最后再看一下16是否为结构体成员变量中最大数据类型,16是8的整数倍,所以是16字节。有图表示为:
data.1 | data.2 | data.3 | data.4 | 空 | 空 | 空 | 空 |
---|---|---|---|---|---|---|---|
*next.1 | *next.2 | *next.3 | *next.4 | *next.5 | *next.6 | *next.7 | *next.8 |
以上就是计算结构体的规则,一定要保证两条规则同时满足才是正确的。
验证
1 |
|
总结
问题一,没有考虑到内存对齐原理
问题二,好傻的一个问题,这不明显head
是一个指针变量
吗,指针变量
当然就是存储在指针变量该待的一个小房间里嘛,还想跑到人家结点
的大房间里,人间结点可是有两个卧室的人啊,一个卧室装数据,一个卧室装指针。你个小小的head
指针变量,只配住在你小小的指针变量
房间里。
参考资料
[1] bigbee2333. 结构体在内存中占用的空间. CSDN博客. 2018. https://blog.csdn.net/weixin_41666244/article/details/80552012