我正在学习 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()*/
}
在这种情况下,函数 func
和 func1
根本没有在程序中被调用,但是那些中的 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/