繁体   English   中英

这段代码会导致内存泄漏吗(Arduino)

[英]Can this code cause a memory leak (Arduino)

我有一个arduino项目,并创建了以下结构:

struct Project {
  boolean         status;
  String          name;
  struct Project* nextProject;
};

在我的应用程序中,我解析一些数据并创建Project对象。 为了将它们包含在列表中,每个Project对象中都有一个指向nextProject的指针(期望最后一个)。 这是我添加新项目的代码:

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

首先,您不需要变量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 -block内继续执行。

因此,现在您的reset -Method需要释放分配给所有项目的内存,就像您的代码一样,不仅释放最后一个项目,而且释放第二个项目。

delete ptrToLastProject; // Free last project
delete firstProject.nextProject; // Free the project following to the first one.

这里的问题是:

  • 如果ptrToLastProject == firstProject.nextProject怎么ptrToLastProject == firstProject.nextProject 第二个delete -statement将释放已经释放的内存。
  • 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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM