计算机基础实战课
彭东
网名 LMOS,Intel 傲腾项目关键开发者
19719 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 57 讲
计算机基础实战课
15
15
1.0x
00:00/00:00
登录|注册

25|堆&栈:堆与栈的区别和应用

你好,我是 LMOS。
在上一课中,我们讲了虚拟内存和物理内存,明白了虚拟内存是一个假想的地址空间,想要真正工作运行起来,就必须要经过 MMU 把虚拟地址转换成物理地址,寻址索引到真正的 DRAM。
今天,我们继续深入到应用程序的虚拟内存地址空间中,弄清楚一个常规应用程序的虚拟内存地址空间中都有哪些东西。首先,我们看看里面的整体布局,然后看看里面的堆与栈,最后我还会重点带你了解一下堆与栈的区别和应用场景。
课程的配套代码你可以从这里下载。

应用程序的虚拟内存布局

你可以把应用程序的虚拟内存,想成一个房子。房子自然要有个合理的布局,有卧室、客厅、厨房这些不同的房间。同样地,应用程序的虚拟内存,承载着应用程序的指令、数据、资源等各种信息。
既然我们想要观察应用程序的虚拟内存布局,首先得有一个应用程序。当然,你也可以观察系统正在运行的应用程序,但是这些应用往往是很复杂的。
为了找到一个足够简单、又能说明问题的观察对象,我们还是自己动手写一个应用,代码如下所示:
#include "stdio.h"
#include "stdlib.h"
#include "unistd.h"
//下面变量来自于链接器
extern int __executable_start,etext, edata, __bss_start, end;
int main()
{
char c;
printf("Text段,程序运行时指令数据开始:%p,结束:%p\n", &__executable_start, &etext);
printf("Data段,程序运行时初始化全局变量和静态变量的数据开始:%p,结束:%p\n", &etext, &edata);
printf("Bss段,程序运行时未初始化全局变量和静态变量的数据开始:%p,结束:%p\n", &__bss_start, &end);
while(1)
{
printf("(pid:%d)应用程序正在运行,请输入:c,退出\n", getpid());
printf("请输入:");
c = getchar();
if(c == 'c')
{
printf("应用程序退出\n");
return 0;
}
printf("%c\n", c);
}
return 0;
}
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入介绍了虚拟内存中的堆和栈的概念及其在应用程序中的作用。首先,通过一个简单的应用程序示例展示了虚拟内存的布局,包括Text段、Data段、Bss段等。然后,重点介绍了堆的概念和操作系统为应用程序建立的堆,以及堆的动态增减内存空间的特性。接着,文章详细解释了栈的本质和特点,强调了堆和栈的区别及其在计算机硬件、操作系统和编译器中的重要性。通过代码示例验证了函数中局部变量在栈中的存储方式。总结了堆和栈的区别和应用场景,强调了它们在现代计算机运行中的重要性。整体来说,本文通过深入的技术解释和实例验证,帮助读者全面了解了虚拟内存中堆和栈的概念及其在应用程序中的作用。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《计算机基础实战课》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(5)

  • 最新
  • 精选
  • 苏流郁宓
    堆,栈由编译器分配,应为虚拟空间!栈是一类数据结构,先入后出!cpu采用时钟轮换制,应对不同的应用软件!取栈入栈由cpu的栈指针决定,栈对c的好处,不仅仅理清数据结构,当cpu遇到中断时 ,可将运行的数据压入栈内存中,先应对中断问题,应对完毕,再从栈内存中取数据(这是栈好处之一) 还有模拟数据的原子化(要么都执行,要么都不执行),在dos模式下,栈最大量为64kb(不知保护模式最大量是多少) 虚拟内存数据是在mmu加载在物理内存上,才正式被cpu运算!不管是栈结构还是堆结构,都是连续的内存空间,但实际物理内存没那么理想,也就是在虚拟内存上连续的栈结构,但通过mmu加载到内存上,可能相邻的两个指令分配在不同的内存页上的

    作者回复: 对的 正确

    2022-09-21归属地:湖北
    7
  • LockedX
    堆、栈空间是虚拟内存空间,当然是需要用到内存的时候分配物理空间啦

    作者回复: 是的

    2022-09-22归属地:湖北
    1
  • peter
    请教老师几个问题: Q1:main.elf包含的五个段,就是文中第二个图所示的五个段吗? 文中第二个图,就是那个竖直条形图。 Q2:“把堆看作一棵树的数组对象”,这句话怎么理解? 堆用树来表示,树中有很多节点,所有节点放在数组里,是这样理解吗? Q3:文中main.map的图中,中间的inode =0 表示什么? 文中第一个图,是main.map的图,文件inode列,共有四个0,第一个0是heap,最后两个0是stack,那中间的0表示什么? Q4:堆测试的图中,图中打印的结果是:alloc = 0x684000, alloc2 =0x684001, 但按照sbrk的功能,alloc应该是0x684001,alloc2应该是0x685001。 为什么会是 不同的值? Q5:本课中所讲的5个段,对于C程序来说是这样。C++程序也是这样吗?

    作者回复: Q1 是的 Q2 是的 你理解的对

    2022-09-22归属地:湖北
  • 相逢是缘
    linux下的多线程程序,每个线程都有自己的栈空间,这个栈空间一定是在本课程中讲的栈空间中分配的吗?如果是在这个栈空间中分配的,没开启一个线程,这个栈空间是怎么分配的呢?(每个线程就固定一个大小?)
    2023-10-31归属地:中国香港
  • goforit
    为什么我的栈输出结果的顺序是 1的3,2,1; 2的3,2,1 和老师的 1,2,3正好反过来
    2023-02-01归属地:广东
收起评论
显示
设置
留言
5
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部