C 全局变量(内存绑定)

C 全局变量(内存绑定),c,static,global-variables,C,Static,Global Variables,考虑以下代码: #include<stdio.h> int a=0; int main() { //some code } #包括 int a=0; int main() { //一些代码 } 我了解到静态变量的物理内存绑定是在加载时完成的。 “a”的内存绑定何时完成?它存储在哪里,在堆栈区域还是静态区域?a在静态存储中,因为它是全局的。堆栈上只有函数的局部变量 您可以在函数中使用static关键字,使该变量的存储类型也是静态的 但是,globals上的静态具有不同的含义(因为

考虑以下代码:

#include<stdio.h>
int a=0;

int main()
{
//some code
}
#包括
int a=0;
int main()
{
//一些代码
}
我了解到静态变量的物理内存绑定是在加载时完成的。
“a”的内存绑定何时完成?它存储在哪里,在堆栈区域还是静态区域?

a
静态存储中,因为它是全局的。堆栈上只有函数的局部变量

您可以在函数中使用
static
关键字,使该变量的存储类型也是静态的


但是,globals上的静态具有不同的含义(因为它们已经是静态存储类型):变量的符号不会导出到目标文件中,因此无法从其他模块(.c文件)直接访问变量。

如前所述,一般行为取决于平台,因此没有普遍有效的答案,但在大多数现代“正常”系统上,编译器会在生成的对象文件中生成一个
.data
部分,其中包含您定义的变量的初始化值

当您启动程序时,程序加载器内存将可执行文件中的
.data
部分直接映射到新创建的进程虚拟内存中,可供您的程序读取和写入(可能使用某些COW方案使每个进程的副本保持私有)


您使用的术语“内存绑定”不是普通术语的一部分,因此我不知道您到底在问什么,但这可能会有所帮助?

编译时,编译器知道“a”是一个全局变量,并将“a”放入可执行文件的数据部分。在该区域中,可执行文件记录“a”的虚拟地址。当可执行文件加载到操作系统中运行时,并且在运行期间使用了“a”,操作系统将物理地址映射到虚拟地址“a”。可执行文件的其余代码只需要知道“a”的虚拟地址即可访问它,操作系统将进行映射并转到物理内存进行读/写。“a”的虚拟地址由编译器在编译过程中确定


关于更多的知识,书“计算机系统:程序员的观点”是一个很好的来源

这取决于平台。@Oli Charlesworth您能给出一个直觉吗?因为内存、变量等的排列不是由C语言定义的。请编译程序并查看生成的对象文件。(GNU/linux的objdump)顺便说一句:main中缺少一个return语句。(在c99中允许,但仍然很松散)顺便说一句:要查看内存中的程序
,您可以使用调试器并检查
a
的值。侧向:
a
必须在对象文件中,因为其他对象可以引用它。虽然这是最常见的行为,但这不是强制性的。编译器/平台在存储方面可以自由地做任何事情。所谓内存绑定,我指的是为变量分配实际物理内存的时间。在这种情况下,我想我的答案是:在程序加载时。不过,严格地说,当时它只分配了虚拟内存。严格地说,现代系统只会在您触摸该部分时才分配物理内存(如果您从未写入该部分,而只是读取该部分,则您的进程可能永远不会获得独占内存分配,因为该部分可能可与其他进程共享)。