我正在学习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
变量分配内存的用途。为什么编译器在通过函数时不能在数据段中为它们分配内存。
我已经解决了有关此问题的堆栈溢出问题,无法得到确切答案 请帮忙!!!
答案 0 :(得分:5)
在编译时分配和初始化内存意味着程序不必跟踪函数是否已经输入并且变量已经初始化。具有常量初始值的局部静态变量被视为与全局变量基本相同,除了该名称仅在该函数的范围内。
这是一个时空权衡 - 在第一次调用期间初始化它需要每次调用函数时都必须执行的代码。在程序加载时初始化它意味着它的初始化是作为从可执行文件段到内存数据段的块复制的一部分以及全局静态完成的。
有关更复杂的C ++本地静态变量的情况,请参阅What is the lifetime of a static variable in a C++ function?。在C ++中,我可能会使用静态std::array
,我认为在输入函数之前我不会初始化它。
如果你在一个很少调用的函数中有一个大数组,并且你不想为它浪费内存,请使用静态指针而不是静态数组,并自己初始化它。 / p>
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;
}
}
...
}
这是编译器为了首次初始化数组而必须生成的代码。