Может ли этот код вызвать утечку памяти (Arduino)

У меня есть проект 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

Решение

Прежде всего, вам не нужна переменная startProject — просто инициализировать firstProject указатель с NULL и затем напишите ваше условие следующим образом:

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,

3

Другие решения

Ваш reset функция должна перебирать цепочку проектов, а не просто удалять первый и последний

1

По вопросам рекламы [email protected]