【问题标题】:Memory managment in c++c++中的内存管理
【发布时间】:2016-05-11 14:00:32
【问题描述】:

假设我们有两个 C++ 代码片段:

1:

void fun1()
{
    if(1)
        int a=5;
}

2:

void fun2()
{
    if(1)
        {
            int *b = new int;
            b = 5;
            delete b;
        }
}

它们是等价的吗?程序离开if 块后,分配给a 变量的内存是否被释放?如果没有,什么时候释放?

【问题讨论】:

  • 您可能想要*b = 5 而不是b = 5。不,这些是不等价的,因为第一个分配在堆栈上,而第二个分配在堆上。
  • 和 Holt 所说的一样,请注意堆栈分配比堆分配快得多。
  • 好吧,第一个可能根本没有分配到任何地方,或者(如果是的话)它只是您的 数据段 中的固定内存位置(不是在堆栈上,顺便说一句)但它确实是一个编译器的东西,它会做它喜欢做的事情 - 假设没有特殊的存储修饰符(我也假设缺少 * 只是一个错字......)
  • 我想您可以使用 sizeof() 函数自己确定这一点。这是我要迈出的第一步。 @Holt 是正确的,你的 b = 5 没有做你期望的事情。
  • 最大的不同是1是惯用的,2是反模式。尽可能使用值语义。其余部分使用智能指针。 no naked new

标签: c++ memory


【解决方案1】:

当函数完成时,'a' 和 'b' 都将从内存中释放。 'a' 将被释放,因为它离开了范围,'b' 将被释放,因为您明确调用了 delete。

它们在内存方面并不相同。在 fun1() 中,您将一个 int 分配给您的堆栈。在 fun2() 中,您在堆栈中分配一个 int 指针,在堆中分配一个 int。这意味着 fun2() 会稍微慢一些并且使用更多的内存。

【讨论】:

  • C++ 没有栈和堆的概念。这些是编译器的实现细节。变量是根据存储持续时间自动/静态/动态定义的。
【解决方案2】:

它们不等价。在fun1 中,a 可能是一个寄存器,也可能是堆栈上的一个位置,具体取决于编译器优化。无论哪种方式,它都会在 if “块”之后超出范围。在fun2 中,您的存储将在堆上。一般来说,对于小型和短暂的对象,fun1 的性能将远远超过fun2

【讨论】:

    【解决方案3】:

    假设您在第二个函数中有错字。

    它们是等价的吗?

    第一个函数几乎什么都不做,而第二个函数将调用可能重载的运算符 new 和也可能重载的运算符 delete。这将分配动态内存并最终释放它。 更重要的是,第二个函数可以抛出异常。

    程序离开 if 块后,分配给 a 变量的内存是否释放?

    在第一个函数中,如果内存已分配,则在离开作用域后将被释放。在第二个示例中,内存将在执行 delete 运算符后被释放,但请记住,您有一个指针作为局部变量,它将像第一种情况一样执行。

    【讨论】:

      【解决方案4】:

      { ... } 被称为复合语句。如果在if 语句中省略了大括号,则包含的语句仍然是复合语句。复合语句具有块范围。这意味着具有自动存储的变量在块作用域结束时被销毁。

      void fun1()
      {
          if(1)
              int a=5; // a destroyed at semi-colon
      }
      
      void fun2()
      {
          if(1)
              {
                  int *b = new int;
                  b = 5;
                  delete b;
              } // b destroyed at brace
      }
      

      new int分配的内存的寿命与b的存储时长无关。这也是推荐使用智能指针的原因之一,这样就不用担心会破坏b管理的内存。

      【讨论】:

        猜你喜欢
        • 2010-09-06
        • 2018-12-17
        • 2013-04-13
        • 2011-06-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多