0

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?

4

2 に答える 2

3

まず、変数は必要ありません。ポインタを NULL でstartProject初期化してから、次の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は、NULL と同様に 0 として定義されます。が NULL の場合firstProject、式は次のようになり、ブロックif (FALSE)内で実行を継続しelseます。

したがって、reset-Method は、コードのように最後のプロジェクトと 2 番目のプロジェクトだけでなく、すべてのプロジェクトに割り当てられたメモリを解放する必要があります。

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

ここでの問題は次のとおりです。

  • もしもptrToLastProject == firstProject.nextProject?2 番目のdeleteステートメントは、すでに解放されているメモリを解放します。
  • firstProjectリリースされることはありません
  • 2 番目と最後のプロジェクトの間のプロジェクトはリリースされません。

単独でリンクされたリストを解放する最良の方法は、次のようなものです:

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 に答える