【问题标题】:Memory mapping for static variables静态变量的内存映射
【发布时间】:2014-12-05 08:51:47
【问题描述】:

来源:

func_1()
{
    static int i = 10;
    printf("%s : %d\n", __func__, i);
}

func_2()
{
    static int i = 20;
    printf("%s : %d\n", __func__, i);
}

main() {
    static int i = 30;
    func_1();
    func_2();
    printf("%s : %d\n", __func__, i);
}

输出:

func_1 : 10
func_2 : 20
main : 30

编译器如何根据函数区分数据段中的变量?

【问题讨论】:

  • 不清楚你在问什么。你是在问编译器如何知道它在什么范围内?
  • 如何编译器处理它没有指定,这取决于编译器。只要它的行为符合规定,真的很重要吗?
  • @DavidSchwartz 是的。另外,如何获取实际值。
  • 就像使用 全局 静态变量一样,这些变量共享 相同 名称,但位于 不同 源文件中.它只是在每个变量前面加上一个唯一的前缀,然后再遍历代码并将它们转换为内存地址。这只是编译过程中的另一个阶段。
  • @JoachimPileborg 好的.. 处理取决于编译器。但是,如何管理数据段以获取数据?这也取决于编译器吗?

标签: c memory-management static


【解决方案1】:

名称i 只是每个函数的局部范围,而每个这样的变量都存储在自己的区域中。编译器生成代码,以便它们中的每一个都从不同的内存地址加载。

【讨论】:

    【解决方案2】:

    编译器可能有不止一种方法来处理这个问题,但这里有一种选择:

    • 函数一一编译
    • 每当遇到静态变量声明时,请在数据部分分配一个新条目
    • 每当遇到静态变量引用时,将其替换为新条目的地址

    如果你考虑一下,这个方法也可以应用于非静态局部变量(使用堆栈代替)。

    当然,对于非静态局部变量,地址的完整翻译只会在运行时发生。

    但概念是一样的——函数一旦编译,它的变量名就没有意义了。

    【讨论】:

      【解决方案3】:

      静态变量的范围在定义它的块中是本地的,但它保留函数调用之间的值。在您的情况下,变量 i 有 3 个实例,它们彼此不同。它们中的每一个都存储在不同的内存位置。

      【讨论】:

        【解决方案4】:

        这完全与变量的作用域有关。在这里,三个 i 是三个独立的变量,在定义的特定函数中,每个变量都有自己的范围。

        func_1 : 10 是正确的,因为 i 在此处是 func_1() 的本地。

        func_1()
        {
            static int i = 10;
            printf("%s : %d\n", __func__, i);
        }
        

        func_2 : 20 也是正确的,因为 i 在此处是 func_2() 的本地。

        func_2()
        {
            static int i = 20;
            printf("%s : %d\n", __func__, i);
        }
        

        main : 30 也是正确的,因为imain() 的本地对象。

        旁注:

        1. 如果您认为是因为static 修饰符,所有变量都将被视为一个变量,那么您不会遇到多重定义 错误吗? :-)
        2. 如果localglobal 变量同名,函数将优先考虑local 变量。

        【讨论】:

          【解决方案5】:

          正如@Blagovest Buyukliev 提到的,每个函数中的每个i 都是不同的,并且仅在该函数内。编译后代码不知道变量名称,而只是引用适当的位置/内存地址。

          因此,如果您稍微更改代码以打印i 的地址,您将看到每个i 都有不同的地址。

          func_1()
          {
              static int i = 10;
              printf("%s : %d, %p\n", __func__, i, &i);
          }
          
          func_2()
          {
              static int i = 20;
              printf("%s : %d, %p\n", __func__, i, &i);
          }
          
          main() {
              static int i = 30;
              func_1();
              func_2();
              printf("%s : %d, %p\n", __func__, i, &i);
          }
          

          样本输出

          func_1 : 10, 0x601028
          func_2 : 20, 0x601024
          main : 30, 0x601020
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-05-18
            相关资源
            最近更新 更多