假设我们有 4 个类,如下所示:
class A
{
public:
A(void) : m_B()
{
}
private:
B m_B;
}
class B
{
public:
B(void)
{
m_i = 1;
}
private:
int m_i;
}
class C
{
public:
C(void)
{
m_D = new D();
}
~C(void)
{
delete m_D;
}
private:
D *m_D;
}
class D
{
public:
D(void)
{
m_i = 1;
}
private:
int m_i;
}
假设有 4 种情况:
情况1:A在栈外部分配,B在栈内部分配
A myA1;
情况2:A外部分配在堆上,B内部分配在堆栈上
A *myA2 = new A();
情况3:C外部分配在栈上,D内部分配在堆上
C myC1;
情况4:C在堆外部分配,D在堆内部分配
C *myC2 = new C();
这些案例中发生了什么?例如,在情况2中,我理解指针myA2是在堆栈上分配的,A对象存在于堆中,但是m_B属性呢?我假设堆上也为其分配了空间,因为对象存在于堆空间中是没有意义的,然后它的属性就会超出范围。如果这是真的,那么这是否意味着外部堆分配会覆盖内部堆栈分配?
情况 3 怎么样,myC1 分配在堆栈上,而 m_D 分配在堆上。这里会发生什么?这两个部分是否跨内存分开?如果我从析构函数中删除“删除 m_D”并且 myC1 超出范围,那么在堆上为 m_D 分配的空间是否会出现内存泄漏?
如果有任何教程/文章详细介绍了这一点,我希望有一个链接。
我认为您混淆了“堆栈/堆分配”和“自动变量”。
自动变量当脱离上下文时会自动销毁。
堆栈分配事实是内存是在执行堆栈上分配的。分配在堆栈上的变量是自动变量。
Also, 成员是自动变量当其所有者被销毁时,其析构函数将被调用。对于指针,它们会被销毁,但底层对象不会被销毁,您必须显式调用delete。为了确保底层对象被销毁,您必须使用智能或唯一指针。
换句话说:您必须调用删除的变量/成员不是自动变量。
最后,类的成员被分配在其所有者的同一内存段上。
在你的代码中:
-
A.m_B
是一个自动变量。如果A在栈上,则B也在栈上;如果A在堆上,则B也在栈上。
-
B.m_i
和 D.m_i 是自动变量,将分配在其所有者的同一内存段上
- The pointer
C.m_D
是一个自动变量,但D类型的指向对象不是,你必须在指针上显式调用delete来删除底层对象。因此,指针 C.m_D 分配在同一内存段上,而不是底层对象上。它显然是由 new 分配的,并且将位于堆上。
So:
-
Case 1:一切都在堆栈上并且是自动的(即:自动销毁)。
-
Case 2:
myA2
位于堆上并且不是自动的(您必须delete myA2
)。其成员m_B2
是一个自动变量,当myA2
被摧毁了。也因为myA2
位于堆上,m_B
与类的任何成员一样,也位于堆的同一内存空间中。
-
Case 3:
myC1
位于堆栈上,是一个自动变量,指向的指针m_D
也在堆栈上,但不是所指向的对象m_D
它是由 new 在堆上分配的。
-
Case 4:与情况 3 相同,但是
myC2
位于堆上并且不是自动的。所以你必须删除myC2
(这将删除m_D
).
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)