【问题标题】:Variable creation on heap or stack in C++在 C++ 中的堆或堆栈上创建变量
【发布时间】:2011-04-28 14:36:12
【问题描述】:

Circle 是一个类,具有公共方法GetDiameter()。 下面2组代码有什么区别?

Qn1: 方法 1 是否在 堆栈 上为 c 分配内存(因此不需要空闲内存),而 方法2上为c分配内存(需要手动释放内存)?

Qn2:我们什么时候应该使用方法1或方法2?

方法一:

void Init()
{
 Circle c;
 c.GetDiameter();

 return;
}

方法二:

void Init()
{
 Circle *c = new Circle();
 c->GetDiameter();

 return;
}

【问题讨论】:

  • 你是怎么知道的? :)
  • 我怀疑它。只是想确认一下。

标签: c++ class memory


【解决方案1】:

是的,方法 1 在堆栈上分配,因此无需释放,而方法 2 在必须释放的堆上分配。

  1. 如果您不希望函数结束后的对象,请使用 Stack
  2. 如果您还希望在函数退出后保持对象处于活动状态,请使用堆(前提是您保留分配的地址)

【讨论】:

  • 啊,但是Circle::operator new() 可能会被覆盖以使用alloca() 来分配堆栈内存。不过,该实例仍需要为deleted。我喜欢 C++ :)
  • @Frédéric:我认为这实际上是不允许的。虽然它会编译,但结果几乎肯定是不确定的,因为operator new 被定义为对具有动态存储持续时间的对象执行分配。 alloca() 不返回指向具有动态存储持续时间的内存的指针。但是,符合要求的operator new 重载总是会抛出bad_alloc;不过,这并不是特别有用...
  • 你所说的那些“允许的”、“未定义的”或“符合的”是什么?如果它可以编译,我们会立即发布它;)
【解决方案2】:

作为良好编码习惯的一般规则,请始终尽可能使用方法 1。 仅当您需要在不同位置存储和/或共享指针时才应使用方法 2。仅在方法或类中本地使用的所有对象都应放入堆栈中。

【讨论】:

  • 小注:异常是巨大的对象,其 sizeof(SomeClass) 与整个堆栈大小相当。
【解决方案3】:

在以下情况下使用方法 2:

  • 对象的生命周期超过了函数的作用域 或
  • 当您调用某个返回指针的函数时,即您正在从抽象工厂或类似工厂创建对象。

后一种技术通常用于处理多态性,因此您得到的类型实际上可能不是指针的类型,而是从它派生的类。

当您需要删除返回值时,最好将其包装在智能指针或其他将“自动”销毁的对象中。

如果在函数结束时需要清理,最好通过使用自动对象(如 scoped_ptr 或 auto_ptr)来完成。这确保了即使函数提前终止(例如抛出异常)也能进行清理。这种技术称为 RAII - 资源获取即初始化。

【讨论】:

  • +1,另请注意,一个新的首字母缩略词正在出现 SBRM(范围绑定资源管理),RAII 的同义词,但名称更清晰。
【解决方案4】:

方法一:在栈上分配内存。 方法2:在堆上分配内存。 + 作为一般规则,如果您使用 call 'new' 必须调用 'delete' 来释放内存。

【讨论】:

    【解决方案5】:

    我见过的关于堆与堆栈的最佳讨论之一在这里:heap vs. stack(向下滚动到讨论的中间)

    简短摘要:

  • 堆栈:对象的生命周期由编译器控制
  • 堆:对象的生命周期由程序员控制
  • 【讨论】:

      【解决方案6】:

      堆栈

      • 有限和固定大小
      • Stricked Last in FirstOut 对象生存期(通常限于封闭函数)

      • 大小通常仅受系统内存大小的限制
      • 手动管理的对象生命周期

      这意味着对于只有短生命周期的小对象是理想的。对于大型对象或任何生命周期比创建函数更长的对象,堆是必需的。手动对象生命周期确实意味着如果您不小心,您可能会发生内存泄漏。

      【讨论】:

        【解决方案7】:

        您甚至还没有开始使用指针,而方法 2 已经存在内存泄漏。

        【讨论】:

        • 哎呀,这个^^^
        猜你喜欢
        • 2016-05-20
        • 1970-01-01
        • 2017-07-11
        • 1970-01-01
        • 2021-10-13
        • 1970-01-01
        • 2017-10-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多