c++ - 有什么需要,局部静态变量在编译时分配内存?

标签 c++ c

我正在学习 C 中的 static 变量,并知道 static 变量的内存是在编译时分配的(必须分配多少内存及其虚拟地址是在编译时计算的,实际内存是在程序加载时分配的)在数据段/.bss 中取决于是否初始化

我在一些网站帖子中看到,由于对象/变量的大小是根据变量类型预定义的,因此内存是在编译时分配的。但是我不明白在函数中定义的局部 static 变量的情况下需要这样做,并且其作用域仅在函数内。

考虑以下代码片段:

void func()
{
    static int i;
    /*some logic*/
} 

void func1()
{
    static int data[10] = {1,2,3,4,5,6,7,8,9,10};
    /*some logic*/
}

int main()
{
    /*logic not involving func() and func1()*/
}

在这种情况下,函数 funcfunc1 根本没有在程序中被调用,但是那些中的 static 变量的内存函数在程序加载后立即分配(从我学到的)实际上没有使用。因此,有了这个缺点,为局部 static 变量分配内存有什么用。为什么编译器在通过函数时不能在数据段为它们分配内存。

我已经解决了与此有关的堆栈溢出问题,但无法得到准确的答案 请帮忙!!!

最佳答案

在编译时分配和初始化内存意味着程序不必跟踪函数是否已经进入以及变量是否已经初始化。具有常量初始值的局部静态变量在本质上被视为与全局变量相同,只是名称仅在该函数的范围内。

这是一个时空权衡——在第一次调用期间初始化它需要每次调用函数时都必须执行的代码。在加载程序时初始化它意味着它的初始化是作为从可执行文件的文本段到内存数据段的 block 复制的一部分以及全局静态完成的。

参见 What is the lifetime of a static variable in a C++ function?对于更复杂的 C++ 局部静态变量的情况。在 C++ 中,我可能会使用静态 std::array,我认为在输入函数之前不会对其进行初始化。

如果你在一个很少调用的函数中有一个大数组,并且你不想为它浪费内存,请使用静态指针而不是静态数组,并自己初始化它。

void func1() {
    static int *data;

    if (!data) { // Need to protect this with a mutex if multi-threading
        data = malloc(N * sizeof(int));
        for (int i = 0; i < N; i++) {
            data[i] = i;
        }
    }
    ...
}

这是编译器必须生成的代码,用于对数组进行首次初始化。

关于c++ - 有什么需要,局部静态变量在编译时分配内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44661285/

相关文章:

c++ - 为什么这里的大括号和圆括号初始化之间存在差异?

c++ - openCV 更改颜色后不会复制到图像(opencv 和 c++)

c++ - 带 C 链接的非外部函数

c - Valgrind 错误、大小读取无效和条件跳转或移动取决于未初始化的值

c - 程序不会在第二次 scanf() 时读取

c++ - 当异常发生在国外源代码时,自创建的Minidump-File的Stacktrace无法正确使用

c++ - 友元范围c++

c++ - AStar网格算法仅处理正方形网格吗?

c - Linux 进程调度程序

c - Apache2 模块中的段错误