当由另一个在堆上分配的对象创建时,对象在哪里分配? [复制]

Posted

技术标签:

【中文标题】当由另一个在堆上分配的对象创建时,对象在哪里分配? [复制]【英文标题】:Where Object Is Allocated When Created By Another Object That Was Allocated On Heap? [duplicate] 【发布时间】:2021-04-30 06:42:55 【问题描述】:
class Foo 
    int num;
;

class Bar 
public:
    Bar() 
       Foo f1;
    
;

int main() 
    Bar* b = new Bar();
    return 0;

在上面的代码中,我在堆上创建了一个 Bar (b) 的实例。 在 Bar 的构造函数中,创建了一个 Foo (f1) 的实例。由于 b 是在堆上创建的,而 f1 是临时的,我不确定 - 调用构造函数时它存储在哪里?

对象的内存是在栈上存储的时候自动处理的,那么如果f1存储在堆上,如何在Bar的构造函数完成后自动销毁呢? 另一方面,如果存储在栈上,那么堆上的对象b怎么指向它呢?

【问题讨论】:

【参考方案1】:

b 指向的对象(即Bar 类型的对象)的存储空间分配在上。

但是,f1 不是该对象的一部分。相反,它是一个在调用函数时创建的本地对象(该函数是Bar 的构造函数,但这无关紧要)。并且本地对象都分配在调用栈上,无一例外。

(Nathan 的回答正确地指出 C++ 没有堆栈或堆存储的概念;上面的解释涉及 C++ 的实现,而不是语言定义。)

【讨论】:

这是我一直在寻找的答案。其他相关问题根据 C++ 概念给出答案【参考方案2】:

C++ 没有堆栈和堆内存空间的概念。相反,它具有自动存储期限和动态存储期限。当范围离开/父对象被销毁时,具有自动存储持续时间(您没有使用新的)的东西会被清理。只有当您手动释放为它获取的内存时,动态存储对象才会被清理。

在这种情况下,由于您没有在b 上调用delete 来释放内存,因此b 指向的对象不会被破坏,因此您有内存泄漏。

Bar() 
   Foo f1;

您在构造函数中创建一个对象,一旦构造函数主体退出,编译器将插入代码为您清理f1,因为它具有自动存储期限。


如果您创建具有动态存储持续时间的对象,并且该对象具有具有自动存储持续时间的子对象,则它们仍驻留在为主对象分配的相同内存空间中。只要主对象被正确释放,它的析构函数就会处理清理它内部具有自动存储持续时间的子对象。

【讨论】:

C++ 没有堆和栈的概念,但 实现 有。这似乎是 OP 所要求的。

以上是关于当由另一个在堆上分配的对象创建时,对象在哪里分配? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

静态方法内存分配

我应该啥时候在堆上分配? (C++)

java创建对象时分配内存方式,是堆上分配还是栈上分配?

Java中对象都是分配在堆上吗?你错了!

第二章 - 一切都是对象

Android Dalvik虚拟机 对象创建内存分配流程