簡體   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