【发布时间】:2015-03-13 10:07:12
【问题描述】:
我知道这个问题在 SO 中被问了很多,就像在 Object creation on the stack/heap? 据我了解,如果一个对象存储在 Stack 中,如果变量超出范围,它将被弹出。但是当涉及到自动存储时,它让我感到困惑,它怎么不在堆中。我读过不推荐在 C++ 中使用 new 和 delete (甚至邪恶是词的选择),因为它会引入内存泄漏。所以我设备了一个像这样的测试代码
#include <iostream>
#include <string>
class Cat
{
public:
Cat(const std::string& name)
{
this->name = name;
std::cout << "construct Cat " << this->name << std::endl;
}
~Cat()
{
std::cout << "destruct Cat " << this->name << std::endl;
}
void feed()
{
std::cout << "feed Cat " << this->name << std::endl;
}
private:
std::string name;
};
Cat createFelix()
{
Cat garfield("Garfield");
Cat felix("Felix");
garfield.feed();
felix.feed();
return felix;
}
void getAndFeedFelix()
{
Cat justFelix = createFelix();
justFelix.feed();
}
int main()
{
getAndFeedFelix();
std::cout << "bla bla blah" << std::endl;
}
结果是这样的
construct Cat Garfield
construct Cat Felix
feed Cat Garfield
feed Cat Felix
destruct Cat Garfield
feed Cat Felix
destruct Cat Felix
bla bla blah
所以在我的结论中,函数 createFelix() 是从 getAndFeedFelix() 调用的,它返回一个 Cat(存储在堆栈中),应该在函数返回后从堆栈中弹出,但对象在 @ 之后被破坏由于自动存储机制,987654326@ 超出范围。这怎么可能发生?如果自动存储使用堆和引用计数,那么它可能是可能的。我的逻辑错了吗?
【问题讨论】:
-
自动存储使用的是栈,而不是堆
-
如果你想查看所有细节,你应该实现一个检测的复制构造函数和赋值运算符。
-
“我读过不推荐在 C++ 中使用 new 和 delete(甚至邪恶是词的选择),因为它会引入内存泄漏”。说这话的人并没有在真正的项目上工作过。
-
@RSahu 我认为恰恰相反,在你从事一个真正的项目之后,你倾向于建议不要使用原始指针,而是使用智能指针。
-
@vsoftco,堆内存的使用是你工具箱中的一个工具。一旦你学会了如何使用该工具,它就不再可怕了。仅当您来自为您管理内存的语言时,这才令人恐惧。
标签: c++ oop heap-memory stack-memory