Class members and explicit stack/heap allocation
Let's say we have 4 classes as follows:
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;
}
Lets say there are 4 cases:
case 1: A externally allocated on the stack, B internally allocated on the stack
A myA1;
case 2: A externally allocated on the heap, B internally allocated on the stack
A *myA2 = new A();
case 3: C externally allocated on the stack, D internally allocated on the heap
C myC1;
case 4: C externally allocated on the heap, D internally allocated on the heap
C *myC2 = new C();
What goes on in each of these cases? For example, in case 2, I understand the pointer myA2 is allocated on the stack, the A object exists in the heap, but what about the m_B attribute? I assume space on the heap allocated for it as well because it wouldn't make sense for an object to exist in heap space and then it's attribute goes out of scope. If this is true then does that mean the external heap allocation overrides the internal stack allocation?
What about case 3, myC1 is allocated on the stack, however m_D is allocated on the heap. What happens here? Are the two parts split across memory? If I removed the 'delete m_D' from the destructor and myC1 went out of scope, would there be a memory leak for the space allocated on the heap for m_D?
If there are any tutorials/articles that go over this in detail I would love a link.
I think that you are confusing "stack/heap allocation" and "automatic variable".
Automatic variables are automatically destroyed when going out of context.
Stack allocation is the fact that the memory is allocated on the execution stack. And variable allocated on the stack are automatic variables.
Also, members are automatic variables whose destructors get called when its owner is destroyed. In the case of pointers, they are destroyed but not the underlying object, you have to explicitly call delete. To make sure that the underlying object is destroyed you have to use smart or unique pointers.
To put it another way: variables/members that you have to call delete on, are not automatic variables.
Lastly, member of a class are allocated on the same memory segment of the its owner.
In you code:
A.m_B
is an automatic variable. If A is on the stack so is B and is A is on the heap so is B. B.m_i
and D.m_i are an automatic variables and will be allocated on the same memory segment of their owner C.m_D
is an automatic variable, but the pointed object of type D is not, you have to explicitly call delete on the pointer to delete the underlying object. So, the pointer C.m_D is allocated on the same memory segment, but not the underlying objet. It's cleary allocated by new and will be on the heap. So:
myA2
is on the heap and not automatic (you have to delete myA2
). Its member m_B2
is an automatic variable that will be destroyed when myA2
is destroyed. Also since myA2
is on the heap, m_B
, like any member of a class, is in the same memory space the heap too. myC1
is on the stack and is an automatic variable, The pointer to m_D
is on the stack too, but not the object pointed by m_D
which is allocated by new on the heap. myC2
is on the heap and is not automatic. So you have to delete myC2
(which will delete m_D
). Case 1: everything on the "stack" (automatic storage). Resources are released as you exit scope.
Case 2: myA2
is on the "heap", so is it's m_B
, and you only have to worry about releasing the resources taken up by myA2
. it's m_B
will be destructed automatically when myA2
is.
Case 3: myC1
is on the stack, it's m_D
points to a D
on the heap, but the C
destructor takes care of deleting it, so as myC1
goes out of scope, all dynamically allocated resources are cleared.
Case 4: myC2
dynamically allocated, to it must be deleted to release resources taken by it. Deleting it will call it's constructor which in turn will take care of it's m_D
, as in case 3.
I am not sure about articles, I am sure there are plenty around. But I suggest reading some good C++ books
Your object is a piece of organised memory. Object does not allocate it's members on the stack, it just consists of it's members.
Case 2: the whole object exists in the heap, this means that all it's members lie in the heap.
Case 3: the whole object exists on the stack. The trick is that it's not D
class instance who is member of myC1
, but pointer-to-B is physically member of myC1
. So member of myC1
lies on stack and points to some D
instance that lies in the heap.
上一篇: jQuery获取特定的选项标签文本
下一篇: 类成员和显式堆栈/堆分配