据我所知,每当我们运行任何程序时,程序的机器指令都会加载到RAM中。同样,有两个内存区域:堆栈和堆。
我的问题是:机器指令存储在哪个内存区域?堆栈还是堆?
我了解到,虽然函数内部没有声明变量,但以下程序会产生运行时错误。这背后的原因是堆栈溢出。那么我应该假设函数的机器指令存储在堆栈中吗?
int func()
{
return func();
}
答案 0 :(得分:9)
两者都没有,因为它不是以动态动态分配堆栈和堆的方式。
可执行加载程序将可执行文件(.text)及其包含的任何静态数据(如全局变量的初始值(.data / .rodata))加载到未使用的RAM区域中。然后它设置可执行文件要求的任何零初始化内存(.bss)。
只有然后是为main()
设置的堆栈。如果输入另一个函数,堆栈内存在堆栈上分配,包含返回地址,函数参数和任何本地声明的变量以及通过alloca()
分配的任何内存。[1]从函数返回时释放内存。
堆内存由malloc()
,calloc()
或realloc()
分配。它会在您free()
或realloc()
时发布。
用于可执行文件的RAM及其静态数据在进程终止之前不会被释放。
因此,堆栈和堆基本上是在应用程序的控制之下。可执行文件本身的内存受可执行加载程序/操作系统的控制。在配备适当的操作系统中,您甚至无法对该内存进行写访问。
关于您编辑的问题,没有。 (糟糕的风格,编辑一个问题,给它一个全新的角度。)
可执行代码仍保留在加载位置。 调用函数不将机器指令放在堆栈上。你的func()
(一个没有参数的函数)唯一存在于堆栈上的是返回地址,这是一个指示当前函数返回后执行应该继续的位置的指针。
由于所有调用都没有返回,因此您的程序会不断在堆栈上添加返回地址,直到它不再存在为止。这根本与机器代码指令无关。
[1]:请注意,这些实际上并不是C语言标准的一部分,而是实现定义的,并且可能不同 - 我提供了事务的简化版本。例如,函数参数可能在CPU寄存器中传递,而不是在堆栈中传递。
答案 1 :(得分:3)
既不是一个也不是另一个。
程序的图像包含代码和静态数据(例如,所有字符串常量,静态数组和结构等)。它们将被加载到RAM的不同部分。
堆栈和堆是用于存储数据的动态结构,它们将在程序开始时创建。 Stack是硬件支持的解决方案,而heap是标准库支持的解决方案。
因此,您的代码将位于代码段中,您的静态数据和堆将位于数据段中,并且堆栈将位于堆栈段中。
答案 2 :(得分:2)
程序的机器指令加载到RAM中
正确托管,#34; PC-like"系统。在嵌入式系统上,代码通常直接从闪存中执行
同样,存在两个内存区域:堆栈和堆。
不,这种过度简化太多了,编程老师教的方式太糟糕了。
还有很多其他区域:.data
和.bss
其中所有带静态存储的变量都去,.rodata
其中常量等等等。
存储程序代码的段通常称为.text
。
答案 3 :(得分:1)
无论是堆还是堆栈。
通常,可执行指令存在于Code segment。
中引用维基百科文章
在计算中,代码段(也称为文本段或简称为文本)是目标文件的一部分或程序虚拟地址空间的相应部分,其中包含可执行指令。
和
当加载程序将程序放入内存以便执行时,会分配各种内存区域(特别是作为页面)
在运行时,目标文件的代码段被加载到内存中的相应代码段中。特别是,它与堆栈或堆无关。
编辑:
在上面的代码段中,您遇到的内容称为无限递归。
即使你的功能在局部变量的堆栈中不需要任何空间,仍然需要推送 外部的返回地址在调用内部函数之前的函数,从而声称堆栈空间,永远不会return
[弹出堆栈中的地址] [如 at a不归点],从而耗尽堆栈空间,导致堆栈溢出。
答案 4 :(得分:1)
同样,存在两个内存区域:堆栈和堆。
这不是那么简单。通常在主流操作系统上会有更多的东西在继续:
因此,代码存储在可执行文件的相关部分中,该部分映射到内存中。
答案 5 :(得分:1)
它们通常位于名为.text
的部分。
在Linux上,您可以使用来自core-utils的size
命令列出ELF对象或可执行文件的部分,例如tst
ELF可执行文件:
$ size -Ax tst | grep "^\.text"
.text 0x1e8 0x4003b0
$
答案 6 :(得分:1)
除了堆栈和堆之外,还有多个内存段。以下是程序如何在内存中布局的示例:
+------------------------+
high address | Command line arguments |
| and environment vars |
+------------------------+
| stack |
| - - - - - - - - - - - |
| | |
| V |
| |
| ^ |
| | |
| - - - - - - - - - - - |
| heap |
+------------------------+
| global and read- |
| only data |
+------------------------+
| program text |
low address | (machine code) |
+------------------------+
详细信息因平台而异,但这种布局在基于x86的系统中非常常见。机器代码占用自己的内存段(ELF格式标记为.text
),全局只读数据将存储在另一个段(.rdata
或.rodata
)中,未初始化的全局变量存储在另一个段中segment(.bss
)等。某些段是只读的,有些是可写的。