对树节点使用 CString 时出现内存泄漏
Memory leak when using CString for tree node
我想在对话框中保存(序列化(MFC树控件,并在初始化对话框时调用它以填充树。 我认为处理该任务的方法是首先编写一个程序,该程序创建树的(最好(矢量表示,将其存储在文本文件中,然后通过从保存的文件反序列化来重新创建树表示。 我也更愿意将节点保存为 CStrings,因为这是我习惯于保存和读取文件中文本的方式。 然而,我不仅不能在这个基础上到达一垒,我甚至不能拿起球棒。 以下使用 std::string 创建单个节点的最小代码运行正常。
#include <string>
#include <vector>
// A node of N-ary tree
struct Node {
std::string key;
std::vector<Node*> child; // An array of pointers for children
};
// A utility function to create a new N-ary tree node
Node* newNode(std::string key)
{
Node* temp = new Node;
temp->key = key;
return temp;
}
// A utility function to create a tree
Node* createTree()
{
Node* root = newNode( "Root" );
return root;
}
int main()
{
Node* root = createTree();
return 0;
}
但是如果我将其更改为使用 CString,
#include <afx.h>
#include <tchar.h>
#include <vector>
struct Node {
CString key;
std::vector<Node*> child; // An array of pointers for children
};
Node* newNode(CString key)
{
Node* temp = new Node;
temp->key = key;
return temp;
}
Node* createTree()
{
Node* root = newNode( _T("Root") );
return root;
}
。当程序退出时,它会报告内存泄漏。有人可以解释一下为什么,如果我能做些什么来纠正它?
正如前面的答案和评论所指出的,有人必须释放所有分配的内存。
当您使用new
时,责任在于您。
但是,C++提供了智能指针,可以为您管理内存分配和释放;请参阅 https://en.cppreference.com/w/cpp/memory/unique_ptr。
您的示例代码将如下所示:
#include <atlstr.h>
#include <tchar.h>
#include <vector>
#include <memory>
struct Node {
CString key;
std::vector<std::unique_ptr<Node>> child;
};
std::unique_ptr<Node> newNode(CString key)
{
std::unique_ptr<Node> temp = std::make_unique<Node>();
temp->key = key;
return temp;
}
std::unique_ptr<Node> createTree()
{
std::unique_ptr<Node> root = newNode(_T("Root"));
root->child.push_back(newNode(_T("Child")));
return root;
}
在评论中附加每个问题:
CString encode(std::unique_ptr<Node>& root)
{
if (root == nullptr)
return _T("");
{
CString sRep = root->key;
for (auto& temp : root->child)
sRep += encode(temp);
return sRep += _T("|");
}
}
您的原始迭代中似乎也有内存泄漏(不使用CString
(。你在堆上为newNode(std::string)
中的new Node
分配内存,但你从不调用delete
。
只需在退出之前delete root;
某个地方main()
即可修复第一个内存泄漏。
接下来,您会发现一旦使用指针填充vector<Node*> child
,也需要以某种方式删除这些指针。我建议在你的struct Node
中添加一个析构函数,它遍历向量并显式调用 delete。
关于CString
的说明
快速搜索CString
的工作原理[1](因为我以前从未处理过它(表明,当您创建CString
的副本(例如使用复制赋值运算符(时,不会创建新对象,但在原始CString
对象中会递增引用计数器。仅当引用计数器达到零时,才会销毁该对象。
由于您永远不会在 Node 指针上调用delete
,因此永远不会删除 Node 对象中的CString
对象,并且永远不会减少此引用编号。调用删除应该可以解决问题,但请报告是否可以解决问题。
- 从构造函数抛出异常时如何克服内存泄漏
- malloc() 可能出现内存泄漏
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 尽管遵循了规则,内存泄漏在哪里
- 为什么调用堆栈数组会导致内存泄漏
- 在简单示例中,Python3 + ctypes 回调会导致内存泄漏
- 使用模板类的自定义列表类型中的内存泄漏
- 为什么以下C++代码中存在内存泄漏?
- OpenCV 我应该使用智能指针来防止内存泄漏吗?
- 我是否生成线程并导致内存泄漏?
- 多线程程序中出现意外的内存泄漏
- 为什么此函数会导致内存泄漏?
- 在 C++ 库中使用cythonized python时内存泄漏
- 需要帮助查找内存泄漏
- 瓦尔格林德的内存泄漏使用新的
- 无法找出我的代码中的内存泄漏
- C++ 结构内部的unordered_map会导致内存泄漏问题吗?
- 可视化 使用 VS Code 查找C++应用程序中的内存泄漏
- Shared_ptr双链接列表内存泄漏
- C++ 在类中使用常量引用文本时 O2 内存泄漏