【问题标题】:What is the need, local static variables are allocated memory during compile time?有什么需要,在编译时为局部静态变量分配内存?
【发布时间】:2017-11-23 11:36:01
【问题描述】:

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

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

考虑以下代码sn-p:

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 变量分配内存有什么用。为什么编译器在经过函数的时候不能在数据段中为它们分配内存。

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

【问题讨论】:

  • “有这个缺点” - 什么缺点?如果编译器必须按照您的建议进行操作,则必须动态分配变量,这意味着它们需要以指针的形式实现。
  • 尝试使用优化进行编译,您可能会发现这些分配永远不会发生。
  • “我没有优化代码”——那当然会很浪费。这就是打开编译器优化的全部意义所在,以使其尽可能多地消除浪费(在内存和操作中)
  • cc++?选择一个。
  • @infiniteloop 当人们谈论优化构建时,他们指的是为发布(Visual Studio 的术语)而不是调试而构建。它们通常并不是要告诉您手动调整代码。

标签: c++ c


【解决方案1】:

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

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

有关 C++ 局部静态变量的更复杂情况,请参阅 What is the lifetime of a static variable in a C++ function?。在 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++ 中,它还必须安排锁定变量以防止通过多个线程进行初始化。
  • 如果静态局部变量是占用大量未使用内存的数组怎么办
  • 请停止重复您的问题。我们理解您的问题。阅读你得到的答案和cmets。有一个权衡,已解释。
  • @FrançoisAndrieux 在 C++ 中我可能会使用一个类,因为在第一次执行代码之前不应该调用构造函数——基本上是 OP 想要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-15
  • 1970-01-01
  • 1970-01-01
  • 2012-08-29
  • 2011-03-17
  • 2020-07-17
相关资源
最近更新 更多