参考资料:《程序员面试宝典》
堆和栈的区别
内存
常用的内存区域有这几部分:
- 代码区:存放函数体的二进制代码
- 数据区:存放全局变量,静态变量等
- 堆区:由人为申请和释放空间
- 栈区:编译器申请和释放空间
堆和栈的区别
1.申请方式
栈:由系统申请和释放
示例:若要声明一个整型变量和字符型变量
int a;
char b;
堆:程序员申请并指明大小,再C语言中常用malloc,calloc,realloc。
示例:若要申请一个一维数组
int* ans = (int*)malloc(sizeof(int) * 10);
2.申请后系统的响应
**栈:**只要栈的剩余空间大于所要申请的空间,系统将为程序提供内存,否则会报 栈溢出(stack overflow).
堆: 首先应该知道操作系统有一个记录空闲内存地址的链表, 当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆节点,然后将该节点从空闲节点链表中删除,并将该节点的空间分配给程序。 对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样,代码中的delete语句才能正确地释放本内存空间。另外,由于找到的堆节点的大小不一定正好等于申请的大小,系统会自动地将多余的那部分重新放入空闲链表中。
3.申请大小的限制
栈: 在windows系统下栈的大小为 1M (1024*1024个字节),在Linux系统下是10M,栈是一块连续的区域,栈顶的地址和栈的容量是系统规定好的。
堆: 正常来说堆的大小为3G左右,是不连续的内存区域。原因是系统用链表来存储空闲内存地址的。所以堆获得空间比较灵活,也比较大。
4.扩展方式
栈: 是从高地址向低地址扩展的数据结构。
堆:是从低地址向高地址扩展的数据结构,因为链表的遍历方向是由低地址向高地址。
图示
5.申请效率比较
栈:由系统自动分配,速度快,程序员无法控制。
堆:由程序员分配,通过 malloc或new,一般速度比较慢,而且容易产生内存碎片,不过用起来方便。
6.存储内容
栈: 在函数调用时,第一个进栈的是主函数的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是各个参数。在大多数编译器中,参数都是从右向左入栈。接着是函数中的局部变量。静态变量不入栈。
当本次函数调用结束后,局部变量先出栈,然后是参数,然后栈顶指针指向最开始存的地址,即主函数中的下一条指令。程序从该点继续运行。
堆:
一般是用堆的头部用一个字节存放堆的大小。具体内容由程序员自己安排。
7.存取效率的比较
示例:
char str1[] = "aaaaaaa";
char* str2 = "bbbbbbbb";
aaaaaaa是在运行时刻赋值的;
bbbbbbbb是在编译时期就确定的。
但在之后的存取中,在栈上的数组比指针指向的字符串(堆)快。
标签:区别,申请,系统,链表,程序员,地址,内存 来源: https://blog.csdn.net/m0_56257585/article/details/120589859
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。