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 all 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:
ptrToLastProject == firstProject.nextProject
? The second delete
-statement would free already released memory.firstProject
gets never releasedThe 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
.