函数内部静态变量的内存分配

时间:2019-01-02 03:38:38

标签: c++ memory static

static void func1(){
    static int i(9);
};

在调用函数或程序启动时是否为静态变量i分配了内存?

2 个答案:

答案 0 :(得分:4)

对于特定情况,取决于实现。首先,分配问题。

该标准确实指出,静态存储持续时间变量是由于程序启动而初始化的。例如,参见C++17 [basic.static.start]

  

(1)具有静态存储持续时间的变量由于程序启动而被初始化。

这似乎表明必须在main甚至开始之前分配内存。但是,C ++(与C一样)也遵循“假设”规则,该规则指出:

  

...只要可以根据以下标准的可观察到的行为确定结果,就可以无视本国际标准的任何要求:该程序。

因此,由于显然无法从函数的外部访问i,因此可以将变量的创建推迟到那时。实际上,由于i即使在函数中也永远不会使用(并且因为它是带有微不足道的构造函数或析构函数的基本类型),因此实际上可以将其永久推迟并优化它的存在:-)

接下来,初始化。前面提到的标准链接对带有常量和非常量表达式的初始化进行了区分。后者,即动态初始化,必须在您首次到达该声明时进行,因为它可能取决于用于初始化它的其他程序变量的当前状态。

但是,由于您使用常量9来初始化整数(并且9在程序执行期间的任何时候都不会改变),因此显然属于常量的初始化部分。标准。在这种情况下,只需要购买变量并将其初始化就可以使用,因此可以在程序启动和初始声明之间的任意 点进行。

这包括在文本中:

  

(3)允许实现以静态或线程存储持续时间对变量进行初始化,作为静态初始化,即使这种初始化不是必须静态进行的,只要(3.1)初始化为动态版本在初始化之前,不更改任何其他静态或线程存储持续时间对象的值; (3.2)如果所有不需要静态初始化的变量都被动态初始化,则静态版本的初始化在初始化变量中产生的值与动态初始化中产生的值相同。


最重要的是,您应该少考虑实施的基本机制,而应该只关注标准规定。

在这种特殊情况下,分配和/或初始化是在main之前还是在首次遇到该声明时进行,都没有区别。一旦开始使用非平凡的构造函数或析构函数,这种情况可能会有所不同,但在这种情况下不会如此。

答案 1 :(得分:1)

在程序启动时分配$.getScript('/js/main.js', function() { // Executes AFTER main.js file is loaded. }); 变量的内存,但是直到第一次调用该函数时才对该变量进行初始化。