在C中,非局部函数和过程变量可以在堆和静态区域中找到吗? 在堆中动态分配的,即使用 malloc 和 calloc。然而,在静态区域中,可以从程序的所有点访问全局变量,对吧? 相反,在堆栈中存在函数或过程的局部变量,对吗?
C 实现存储对象的位置很复杂;它不仅仅取决于变量是否“局部”。
C 标准没有将任何变量定义为“局部”或“全局”。它甚至不使用这些词来描述变量,除了一个与
main
的参数名称相关的传递实例。而且该标准根本没有使用“程序”这个词。
在 C 中,变量由两部分组成:标识符(名称)和用于变量的内存。内存称为对象。
无论在何处声明变量或如何创建对象,在对象的整个生命周期内,都可以在整个程序中访问该对象。在 C 标准中,“访问”意味着读取或写入对象,程序的任何部分如果有对象的地址,就可以读取或写入对象(除了未定义写入使用
const
定义的对象之外)。
如果您关心“局部”和“全局”变量,您可能实际上关心标识符的范围。作用域是程序源代码的区域,其中标识符可用于引用其关联对象(除非它被内部作用域中相同标识符的另一个声明隐藏)。
在普通的通用 C 实现中,对象的存储位置由其“存储持续时间”决定。 C 有四种存储期限:
存储期限:函数内声明的函数参数和对象没有static
具有自动存储期限。这些对象存储在堆栈上,或者由于优化而保存在寄存器中或优化掉(有时是这些对象的混合,包括在不同时间位于不同的寄存器或堆栈上的位置)。
存储持续时间:用_Thread_local
声明的对象具有线程存储持续时间。我没有机会关心它们的存储位置,但我认为它位于创建线程时分配的内存中。
存储持续时间:没有 _Thread_local
声明且在函数外部或带有
static
的函数内部的对象具有静态存储持续时间。您可能会认为这些存储在您所谓的“静态区域”中。然而,它们可能有多个程序部分。值得注意的是,要初始化为零的静态对象可以存储在专门用于该目的的程序段中,而具有非零初始值的静态对象可以存储在另一程序段中。零填充部分在为其提供内存时由操作系统初始化,因此它在程序可执行文件中占用的空间很小。非零填充部分通过将程序可执行文件中的数据读入内存来初始化。
存储持续时间:通过调用内存管理函数创建的对象(例如malloc
和
free
)已分配存储持续时间。用于此目的的内存称为堆,尽管由于历史原因,我们一直使用这个词。