C全局和静态变量存储在内存中

时间:2013-06-06 07:30:26

标签: c

根据我对全局变量和静态变量的了解, 如果在源文件中的所有函数之外声明C变量:

int a;  

一旦该变量在该文件中有外部声明,就可以被其他文件访问 但是如果相同的变量被声明为:

static int a;

那么这个变量只能由当前文件使用,任何其他文件都不能看到这个变量。

  1. 当程序在运行时加载到内存中时,全局和静态变量都出现在该程序的数据部分中。
    我想要理解,因为两者都存储在同一个内存段中,静态变量如何被保护,不会被任何指令用于其范围之外。
    我认为变量的范围及其访问权限将由编译器处理。如果我错了请评论,如果我遗漏任何细节,请添加。

  2. 关于外部变量。 如果

    int a;  
    

    在文件file1.c中定义,并在文件file2.c中声明为:

    extern int a;  
    

    这两个文件属于不同的进程,分别为process1和process2。 因此,当process1正在运行并且其地址空间被加载到内存中时,其数据部分变量“a”将可用 我在这里有一个疑问,就是当process2运行时,这个变量也会加载到process2的数据部分吗?或者如何管理。

  3. 请帮我澄清上面提到的疑惑。 我在网上搜索并阅读了一些文章,需要确认我是否理解是否正确 麻生太郎,请给我一个好的文章或书籍,这将有助于我清楚地理解上述概念。

5 个答案:

答案 0 :(得分:12)

首先,正如您所说,不同的进程具有不同的地址空间。因此,除非您明确地共享它们(共享内存或类似内容),否则它们不共享任何内存。

关于全局静态与全局非静态变量,差异称为 linkage :非静态全局变量具有外部链接,这意味着它们具有名称对于链接器,因此一个编译单元(.c文件)可以访问另一个编译单元中定义的变量。

然而,静态全局变量具有内部链接,因此,尽管它可能位于与前者相同的内存块中,但它没有链接器的名称,因此它不能用于任何其他编译单元而不是它自己的。

答案 1 :(得分:2)

  1. 静态变量在内存中分配了一个地址和一个大小,但它们不会被广告。因此,如果我在一个文件中有static int a;并尝试从另一个文件中使用extern int a;引用它,则无法找到“链接结束”,因此它无效。

    为了让extern发挥作用,必须有“某事”宣传a可用,static不做。

  2. 不,他们不属于不同的流程。它们被链接在一起成为一个可执行文件然后被执行。不同的进程通常无法访问彼此的记忆。

答案 2 :(得分:1)

在文件范围内有一个static变量,使链接器在链接时不可见。编译器不会发出指令,指示符(对应于变量命名)应该对链接器可见。

关于第二个问题,extern int a只是一个声明。它不为该变量保留任何空间,而只是通知编译器这样的变量存在于某处。稍后链接该单元时,链接器将解析对该变量的引用。

答案 3 :(得分:1)

  

1我认为变量的范围及其访问权限将由编译器处理。如果我错了请评论,如果我遗漏任何细节,请添加。

这是正确的。 C编译器不会使其他编译单元可以访问此变量,因此无法成功编译直接访问该变量的程序。 C称这个概念为linkage

您可以编写一个非静态函数来返回其地址以获得对它的间接访问:

static int a;

int *get_a(void)
{ 
  return &a;
}

现在,其他编制单位可以通过调用a

间接访问get_a()

除此之外,由特定的编译器决定在运行时如何表示它。如果你能以某种方式,在C之外,找出a的位置,你就可以随心所欲地使用它。通常没有特殊保护等。

  

2关于外部变量。如果process2正在运行,这个变量也会加载到process2的数据部分吗?或者如何管理。

普通的destktop / server操作系统为每个进程提供虚拟内存。记住,这些进程彼此独立,进程2看到自己的a变量副本,它与进程1中的a副本没有任何关系。唯一常见的是它们是从同一个可执行文件中加载的。

答案 4 :(得分:0)

both files belongs to different processes表示编译器对extern int a;引用的内容绝对没有引用。它不会搜索您计算机上的每一段代码,并希望它找到一个且只有一个int a;声明,然后添加一堆编程来检测和访问该进程的内存。除了可怕的行为之外,复杂程度也是荒谬的,没有实际的保证。