我实现了一个简单的结构:
struct ListenerNode
{
ListenerNode() : previous(nullptr), next(nullptr), listener(nullptr), once(false) {}
std::shared_ptr<ListenerNode> previous;
std::shared_ptr<ListenerNode> next;
std::function<void(int)> listener;
bool once;
};
这将代表场景图实现中的一个实体。我观察到的奇怪行为是当我使用结构时,就像:
int main(int argc, char** argv)
{
ListenerNode n;
}
它会泄漏内存,但当我使用它时:
int main(int argc, char** argv)
{
ListenerNode* n = new ListenerNode();
delete n;
}
它不会泄漏内存!我不明白这里发生了什么。我总是认为当变量超出范围时,不使用new
创建一个类/结构的实例就会立即调用析构函数。
有人可以向我解释一下这里发生了什么吗?我也没有看到任何明显的参考增量。
答案 0 :(得分:7)
根据您的评论,您可以测试内存泄漏,如下面的代码段所示:
int main(int argc, char** argv)
{
ListenerNode n;
_CrtDumpMemoryLeaks();
}
在这种情况下,在调用_CrtDumpMemoryLeaks()
时,n
尚未超出范围。您可以毫无问题地在n
之后访问_CrtDumpMemoryLeaks()
的内容。在遇到n
的右括号后,main()
被破坏。
如果你添加一对额外的大括号:
int main(int argc, char** argv)
{
{ ListenerNode n; }
_CrtDumpMemoryLeaks();
}
然后,当遇到额外的右括号时,n
被破坏。当您拨打_CrtDumpMemoryLeaks()
时,n
根本无法访问,因为它已经超出了范围。
答案 1 :(得分:0)
如果您在班级中创建列表,则会泄漏内存。永远不要使用shared_ptr创建周期(就像你使用next / previous一样),它们不会删除任何内容。
您不需要使用nullptr初始化shard_ptr。