简体   繁体   中英

Can this code cause a memory leak (Arduino)

I have a arduino project and I created this struct:

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

In my application I parse some data and create Project objects. To have them in a list there is a pointer to the nextProject in each Project object expect the last. This is the code where I add new projects:

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 is an private instance variable and defined in the header file like this:

Project firstProject;

So if there actually no project was added, I use firstProject , to add a new one, if firstProject is set I use the nextProject pointer.

Also I have a reset() method that deletes the pointer to the projects:

void RssParser::reset() { 
  delete ptrToLastProject;
  delete firstProject.nextProject;

  startProject = false;
}

After each parsing run I call reset() the problem is that the memory used is not released. If I comment out the addProject method there are no issues with my memory. Someone can tell me what could cause the memory leak?

First of all, you do not need the variable startProject - simply initialize the firstProject pointer with NULL and then write your condition like this:

if (firstProject)
{
    // There is a project, so append the new one.
}
else
{
    // There is no project, so we need to create a new list.
}

The value FALSE is defined as 0, just as NULL. If firstProject is NULL the expression would look like if (FALSE) and continue execution inside the else -block.

So now your reset -Method needs to free the memory allocated for projects, not only the last one and the second one, as your code does. 项目的内存,就像您的代码一样,不仅释放最后一个项目,而且释放第二个项目。

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

The problems in here are:

  • what if ptrToLastProject == firstProject.nextProject ? The second delete -statement would free already released memory.
  • firstProject gets never released
  • the projects between the second and the last ones will never be released.

The best way to free a singly linked list is something like this:

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;
}

In this implementation you are "walking" through the list, releasing the predecessing element, as long as there is an element following. If the next element is NULL , the last element has been released and the loop breaks.

Last but not least you need to reset the pointer to the first element (also called "anchor" in the terms of data structures):

firstProject = NULL;

this ensures that addProject does not try to append an project to NULL .

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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