0

我有一个 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方法,则我的记忆没有问题。有人可以告诉我什么可能导致内存泄漏?

4

2 回答 2

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,则表达式看起来像并在-blockif (FALSE)内继续执行。else

所以现在你的reset-Method 需要释放分配给所有项目的内存,不仅仅是最后一个和第二个,就像你的代码一样。

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.

于 2012-11-20T11:18:33.717 回答
1

您的reset函数需要遍历项目链,而不仅仅是删除第一个和最后一个

于 2012-11-20T11:01:00.527 回答