简单链表结点与头指针内存分析

问题描述

问题一:今天在学习数据结构——链表的过程中,突然想搞明白一下,简单链表,它一个结点占据多大内存啊。

typedef struct linkednode
{
	int data;  
	struct linkednode * next; 
} snode, *ptr; 

ptr head; 

问题二:另外,还有菜鸡的我心中一直有一个疑问,头指针head,它占据多大内存啊,是和一个结点一样大的内存吗?还是只是一个指针所占据的内存大小啊。

结论

首先问题一,结点用的是结构体定义,结构体所占据内存的计算,要满足一个内存对齐原理,所以计算结点所占据的内存,要在对齐原理的前提下,进行计算。我的系统是64位的,用的编译器是Dev C++,我一个结点占据的内存是16字节

然后问题二,头指针head,是一个指针变量,所有的指针变量在我这里,占据的内存都是8字节,不是和结点一样大的内存。它只是一个指针变量,这个变量head指向一个内存占16字节的结点。

typedef struct linkednode  //16字节
{
	int data; //值域 8,int是4,但是由于对齐原理,它是占8 
	struct linkednode * next; //链域 8
} snode, *ptr; 

ptr head; //指针变量,占8

分析

背景

运行环境

操作系统为win10 64位,编译器是Dev C++

内存对齐原理

这是因为为了CPU能够快速的访问,提高访问效率,变量的起始地址应该具有某些特性,这就是所谓的“对齐”。比如这里4字节int型变量,那他的起始地址应该在4字节的边界上,即起始地址可以被4整除。

内存对齐的规则:

  • 起始地址为该变量的类型所占的整数倍,若不足则不足部分用数据填充至所占内存的整数倍。
  • 该结构体所占内存为结构体成员变量中最大数据类型的整数倍。

因此上面的结构体中int data4字节,而*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

以上就是计算结构体的规则,一定要保证两条规则同时满足才是正确的。

验证

#include <iostream>

using namespace std;

typedef struct linkednode
{
	int data; //值域 8,原本是4,但是由于对齐原理,它是占8 
	struct linkednode * next; //链域 8
} snode, *ptr; 


int main(int argc, char** argv) {
	
	ptr head; //定义头指针 
	head = NULL; 
	
	cout << "int size is " << sizeof(int) << endl; //整型int占据内存:4字节 
	cout << "snode size is " << sizeof(snode) << endl; //创建的结点snode占据内存:16字节 
	cout << "ptr size is " << sizeof(ptr) << endl; 
	cout << "head size is " << sizeof(head) << endl; //头指针占据内存:8字节 
	
	cout << endl;
		
	return 0;
}

在这里插入图片描述

总结

问题一,没有考虑到内存对齐原理

问题二,好傻的一个问题,这不明显head是一个指针变量吗,指针变量当然就是存储在指针变量该待的一个小房间里嘛,还想跑到人家结点的大房间里,人间结点可是有两个卧室的人啊,一个卧室装数据,一个卧室装指针。你个小小的head指针变量,只配住在你小小的指针变量房间里。

在这里插入图片描述

参考资料

[1] bigbee2333. 结构体在内存中占用的空间. CSDN博客. 2018. https://blog.csdn.net/weixin_41666244/article/details/80552012

猜你喜欢

转载自blog.csdn.net/ALexander_Monster/article/details/106178159