【问题标题】:Automatic variables in C++ [duplicate]C ++中的自动变量[重复]
【发布时间】:2011-07-06 20:02:51
【问题描述】:

可能重复:
In C++, why should new be used as little as possible?

在 C++ 中自动变量分配在哪里?在栈上还是堆上?

另外,我在 7.9 — The stack and the heap 中读到,堆栈上分配的 所有 内存在编译时是已知的。这是真的吗?这是否意味着堆栈上只发生静态内存分配?

另外,请提及链接,参考关于 C++ 内存分配的完整解释性文本。

【问题讨论】:

  • C++ 变量分配的详细解释见this question
  • C++ 是一种语言,而不是一种实现,因此它没有“堆栈”之类的概念;这些东西留给编译器和特定平台。可能会在堆上分配每个具有自动存储持续时间的对象。但实际上,它始终是堆栈。但请记住,如果您真的需要了解这些信息,您将询问平台,而不是 C++。让 C++ 成为 C++ 语言,别担心。另外,不要从网上学习 C++,你应该得到一个good book
  • @GMan:实际上,自动变量并不总是在堆栈中。看我的回答。
  • @Peter:是的,也许总是有点强,但大多数时候肯定是这样。寄存器是一种非常稀缺的资源。

标签: c++ memory heap-memory stack-memory automatic-properties


【解决方案1】:

C++ 没有堆栈或堆的概念,就语言而言,它是一个实现细节

话虽如此,我所知道的每个实现都使用堆栈来管理局部变量的生命周期。然而,许多局部变量最终可能完全存在于寄存器中并且永远不会接触堆栈,并且一些局部变量可能会被完全优化掉。仅仅因为你声明了一个自动变量并不意味着它会被放入堆栈。

例如

int main()
{
    int x = rand();
    int y = 2;
    cout << x << y << endl;
    return 0;
}

在这段代码中,通过优化,变量y 几乎肯定会被完全删除,变量x 可能会被赋予它自己的寄存器。这些变量中的任何一个都不太可能存在于堆栈中。

【讨论】:

  • 说得好。我讨厌“标准”警察跳进来,只是引用神圣标准的引述就停在那里。很好的例子。
  • 还有一个考虑,即使周围对象有自动存储时长,成员变量也可能引用动态内存。如果vector&lt;int&gt; v; 是自动的,因此很可能在“堆栈”上,那么v[0] 仍然几乎肯定在“堆”上。
  • @Dennis:你说得对,即使向量本身在堆栈上,向量的内容(可能)也会在堆上,但它的成员变量没有用自动声明storage(自动存储类只能与局部变量一起使用,包括参数)所以它似乎与被问到的问题是分开的。
  • 是的,我同意。我的评论主要是为了扩展“局部变量 ==> 堆栈”并不是一个特别有用的简化的想法,即使该语言并未对堆栈实际存在的想法保持沉默。
【解决方案2】:

自动(局部)变量不在堆上分配。它们要么存在于堆栈中,要么存在于寄存器中。

是的,所有堆栈分配在编译时都是已知的。

您引用的链接实际上是描述 c++ 如何处理内存的一个很好的资源。

【讨论】:

    【解决方案3】:

    是的,自动变量通常是在堆栈上分配的(C++ 标准没有指定“堆栈”,但假设它是足够安全的)。

    您可以使用堆栈通过alloca() 函数分配动态内存,但这不是很好的做法,更多关于这个问题:Why is the use of alloca() not considered good practice?

    【讨论】:

      【解决方案4】:

      除了在寄存器或堆栈中定位一些局部变量之外,如果可以在编译时确定对象的可用寿命仅限于代码区域,一些编译器可能会选择重用特定的寄存器或内存.

      例如,

      {
      int a;
      // do something with a
      
      int b;
      // do something with b but nothing with a
      }
      

      编译器会注意到 a 和 b 的大小相同,但 a 在 b 的生命周期内的任何地方都没有使用。编译器会将 a 和 b 映射到同一个内存(堆栈或寄存器),从而节省一点空间。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-03-15
        • 1970-01-01
        • 1970-01-01
        • 2016-07-27
        • 2021-06-23
        • 1970-01-01
        • 2012-04-12
        • 2013-06-09
        相关资源
        最近更新 更多