【问题标题】:Member values on stack or heap?堆栈或堆上的成员值?
【发布时间】:2013-11-18 05:14:42
【问题描述】:

这可能是重复的。但是,我找不到。

怀疑:

让我们假设 A 类和 B 类。

如果我这样做。

A* aPtr = new A;  //This is an heap allocation

如果我这样做

B bObj; //This is stack allocatio

如果我有一个 C 类,它同时具有像这样的 A 和 B obj。

class C
{
   A aObj;
   B bObj;
};

如果C的分配是这样的:

C *cptr = new C; //here memory allocation for cptr is heap. 
                 //But, what about aObj and bObj, which are not heap allocated?

aObj 和 bObj 是否都分配在堆上,尽管它们看起来像堆栈对象?

【问题讨论】:

  • 都是堆分配。 C的构造函数会调用aObj和bObj的构造函数。如果这些构造函数要做一些独特的事情,比如使用私有分配器。 aObj 或 bObj 使用的一些内存可能不是来自堆。但这将是极其罕见的。
  • 如果您停止将它们视为“堆栈”与“堆”并开始将它们视为“自动”与“动态”,这可能会有所帮助(或没有帮助),因为这是逐字记录它们的方式'在标准中有所描述。如果您想更深入地回答此类问题,那么这是一个很好的地方。 C++11 3.7.3 详细描述了Automatic storage duration; C++ 3.7.4 同样适用于动态存储持续时间

标签: c++ memory-management heap-memory stack-memory


【解决方案1】:

在引用 C++ 时,我个人讨厌“堆”和“堆栈”这个词,因为 C++ 标准没有强制要求分配内存的位置。所有标准保证是何时释放内存。

因此,我更喜欢使用名称Dynamic memory allocationAutomatic memory allocation 来区分两者。

自动内存分配将在超出范围或它所在的对象被删除时被删除。

动态内存分配在代码中明确释放时将被删除。

C *cptr = new C; 这样的东西是使用动态内存分配分配的,需要在程序结束之前删除,否则您将有未定义的行为。

B bObj; 将使用自动内存分配,并在它所在的对象被删除时被删除。

【讨论】:

  • 不删除动态内存并不是未定义的行为。该标准似乎没有要求您删除new 返回的指针。许多程序依赖于全局对象的这种行为。
  • @edA-qamort-ora-y 这是未定义的行为,但在现代操作系统上,您可以期望操作系统在程序关闭后进行清理。但 C++ 不能保证这一点。
  • 标准中哪里说它是未定义的?请注意,未指定的或已定义的实现与未定义的行为有很大不同。
【解决方案2】:

aObjbObj 是堆上 C 实例的成员。所以是的,cpt->aObjcpt->bObj 在堆上。

如果你有

C c;

那么c.aObj 在堆栈上,c.bObj 在堆栈上。

【讨论】:

    【解决方案3】:

    在类 C 的声明中,成员 A 和 B 也是声明。使用 operator [new],指针 cptr 将分配在堆中,成员也将在堆中。

    【讨论】:

      猜你喜欢
      • 2018-01-06
      • 2011-02-18
      • 1970-01-01
      • 1970-01-01
      • 2013-05-10
      • 2012-06-05
      • 2018-11-11
      • 2013-01-25
      • 2018-09-09
      相关资源
      最近更新 更多