我有一个arduino项目,我创建了这个结构:
struct Project {
boolean status;
String name;
struct Project* nextProject;
};
在我的应用程序中,我解析了一些数据并创建了Project
个对象。要将它们放在列表中,每个nextProject
对象中都有一个指向Project
的指针。这是我添加新项目的代码:
void RssParser::addProject(boolean tempProjectStatus, String tempData) {
if (!startProject) {
startProject = true;
firstProject.status = tempProjectStatus;
firstProject.name = tempData;
firstProject.nextProject = NULL;
ptrToLastProject = &firstProject;
} else {
ptrToLastProject->nextProject = new Project();
ptrToLastProject->nextProject->status = tempProjectStatus;
ptrToLastProject->nextProject->name = tempData;
ptrToLastProject->nextProject->nextProject = NULL;
ptrToLastProject = ptrToLastProject->nextProject;
}
}
firstProject
是一个私有实例变量,在头文件中定义如下:
Project firstProject;
因此,如果实际上没有添加任何项目,我使用firstProject
添加新项目,如果设置了firstProject
,我使用nextProject
指针。
我还有一个reset()
方法删除指向项目的指针:
void RssParser::reset() {
delete ptrToLastProject;
delete firstProject.nextProject;
startProject = false;
}
每次解析运行后,我调用reset()
,问题是所使用的内存未被释放。如果我注释掉addProject
方法,那么我的记忆就没有问题了。有人可以告诉我什么可能导致内存泄漏?
答案 0 :(得分:3)
首先,您不需要变量startProject
- 只需使用NULL初始化firstProject
指针,然后写下您的条件:
if (firstProject)
{
// There is a project, so append the new one.
}
else
{
// There is no project, so we need to create a new list.
}
值FALSE
定义为0,就像NULL一样。如果firstProject
为NULL,则表达式看起来像if (FALSE)
并继续在else
- 块内执行。
所以现在你的reset
- 方法需要释放为所有项目分配的内存,而不仅仅是最后一个和第二个项目,就像你的代码一样。
delete ptrToLastProject; // Free last project
delete firstProject.nextProject; // Free the project following to the first one.
这里的问题是:
ptrToLastProject == firstProject.nextProject
怎么办?第二个delete
- 语句将释放已释放的内存。firstProject
永远不会被释放释放单链表的最佳方法是:
Project* pProject = firstProject;
Project* pProjectToDelete;
while (pProject) // As long as the pointer points to something (see the first comment)
{
pProjectToDelete = pProject;
pProject = firstProject->nextProject;
delete pProjectToDelte;
}
在此实现中,只要后面有一个元素,您就可以“遍历”列表,释放前导元素。如果下一个元素是NULL
,则释放最后一个元素并且循环中断。
最后但并非最不重要的是,您需要将指针重置为第一个元素(在数据结构方面也称为“锚点”):
firstProject = NULL;
这可确保addProject
不会尝试将项目追加到NULL
。
答案 1 :(得分:1)
您的reset
函数需要迭代项目链,而不仅仅是删除第一个和最后一个