【问题标题】:How to resolve these memory leak in Doubly Linked List?如何解决双向链表中的这些内存泄漏?
【发布时间】:2020-02-03 20:37:00
【问题描述】:

我一直在尝试使用简单的 delete [] 名称来消除内存泄漏,但我认为它没有被成功删除,因为我仍然有内存泄漏。我还有一个 DeleteAll() 函数,它遍历节点但似乎没有删除对象名称。

下面的代码在 add 函数下,我认为这可能是我的内存泄漏的原因: CDoublyLinkedList 类下

        CListNode*      work        = NULL;                 // holds head
        CListNode*      prev        = NULL;                 // previous
        CListNode*      newData     = new CListNode();      // instantiation of node class
        char* name = NULL;                                  //char array for name

        /// ________Increase array size of name depending on input
        name = new char[strlen(iName) + 1];
        /// ________Copy string to char
        strcpy_s(name, strlen(iName) + 1, iName);

        newData->SetName(name);     // Set user input to character list

我的析构函数只包含同一个类下的全部删除函数

void DeleteALL()
    {
        CListNode* next;
        CListNode* current;

        current = head;
        while(current != NULL) {
            next = current->GetNext();
            delete current;
            current = next;
        }
        current = NULL;
        head = NULL;
        tail = NULL;
        next = NULL;
    }

这是我的主要内容:

CDoublyLinkedList       element         =       new CDoublyLinkedList;      //list object
Switch(option) {
            /// ____Option Add name
            case '1':
                cout << "Enter name:" << "\t";
                cin >> temp;

                /// ________If input is not 4-25 characters<br></br>
                /// ____________Loop while input is not 4-25 characters<br></br>
                /// ________________Ask for new input<br></br>
                /// ____________End loop<br></br>
                /// ________End if<br></br>
                if((temp.length() >= 3) == false
                    || (temp.length() <= 25) == false) {

                    while((temp.length() >= 3) == false
                        || (temp.length() <= 25) == false) {

                        cout << "Input should be 3-25 characters. Try again." << "\n";
                        cout << "Enter name:" << "\t";
                        cin >> temp;
                    }
                }
                /// ________Add input to list
                element->AddSortList(temp.c_str());

我通过以下方式删除了 main 方法中的对象:

if(element != NULL) {
        delete[] element;
        element = NULL;
    }

CNode类只包含get和set

class CListNode
{
private:
    CListNode*          mNext;              // Next item pointer
    CListNode*          mPrev;              // Previous item pointer
    char*               mNameElement;       // List element pointer

public:
    /// <summary>
    /// Node initializer to set as NULL
    /// </summary>
    /// <dt>Date:</dt>
    /// 2019/10/03 Created  by JAC.Tayag (SAT-A)    TRAINING
    CListNode()
    {
        mNext = NULL;
        mPrev = NULL;
    }

    ~CListNode()
    {
        CListNode* next;
        CListNode* current;

        current = mPrev;
        while(current != NULL) {
            next = current->GetNext();
            delete current;
            current = next;
        }
        current = NULL;
        mNext = NULL;
        mPrev = NULL;
        next = NULL;
    }
    /// <summary>
    /// Assign input name
    /// </summary>
    /// <dt>Date:</dt>
    /// 2019/10/03 Created  by JAC.Tayag (SAT-A)    TRAINING
    void SetName(char* iNameElement)
    {
        mNameElement = iNameElement;
    }

    /// <summary>
    /// Assign next pointer
    /// </summary>
    /// <dt>Date:</dt>
    /// 2019/10/03 Created  by JAC.Tayag (SAT-A)    TRAINING
    void SetNext(CListNode* iNext)
    {
        mNext = iNext;
    }

    /// <summary>
    /// Assign previous pointer
    /// </summary>
    /// <dt>Date:</dt>
    /// 2019/10/03 Created  by JAC.Tayag (SAT-A)    TRAINING
    void SetPrev(CListNode* iPrev)
    {
        mPrev = iPrev;
    }

    /// <summary>
    /// Return input name
    /// </summary>
    /// <dt>Date:</dt>
    /// 2019/10/03 Created  by JAC.Tayag (SAT-A)    TRAINING
    char* GetName()
    {
        return mNameElement;
    }

    /// <summary>
    /// Return next pointer
    /// </summary>
    /// <dt>Date:</dt>
    /// 2019/10/03 Created  by JAC.Tayag (SAT-A)    TRAINING
    CListNode* GetNext()
    {
        return mNext;
    }

    /// <summary>
    /// Return previous pointer
    /// </summary>
    /// <dt>Date:</dt>
    /// 2019/10/03 Created  by JAC.Tayag (SAT-A)    TRAINING
    CListNode* GetPrev()
    {
        return mPrev;
    }

【问题讨论】:

  • 什么是CDoublyLinkedList? CListNode 是什么?你怎么知道你有内存泄漏?
  • @John3136 我一直在使用这个: if(_CrtMemDifference(&memCheckDiff, &memCheckStart, &memCheckEnd)) { _CrtMemDumpStatistics(&memCheckDiff); _CrtMemDumpStatistics(&memCheckStart); _CrtMemDumpStatistics(&memCheckEnd); } else { _CrtMemDumpStatistics(&memCheckDiff); _CrtMemDumpStatistics(&memCheckStart); _CrtMemDumpStatistics(&memCheckEnd);我的问题是如何删除函数内的对象
  • @John3136 我已添加 CNode 供您参考
  • 至少有一次内存泄漏是由于未能在节点析构函数中释放mNameElement。无论如何,节点不应该释放整个列表。它应该只清理自身。列表(包含整个内容的 CDoubleLinkedList)应该负责迭代和清理。尝试在每个节点间进行操作会导致边缘情况的灾难和混乱。此外,我在这段代码中除了name 之外没有看到任何东西是数组分配的,所以任何delete[] element 的使用都会自动成为一个危险信号。

标签: c++ memory-management destructor doubly-linked-list


【解决方案1】:

你可以像单链表一样删除。

node* element = head;
while( element != 0 ) {
    node* next = element->next;
    delete element;
    element = next;
}
head = 0;

【讨论】:

  • 我将放置在我的主要位置?
  • 您可以放置​​在您要删除的任何函数中。如果它解决了您的问题,请评价并接受我的回答。
  • 但如果我把它放在我的函数上,它也会从列表中删除它?
猜你喜欢
  • 2019-01-01
  • 1970-01-01
  • 2016-09-02
  • 1970-01-01
  • 2014-04-23
  • 2020-05-11
  • 1970-01-01
  • 2015-06-28
  • 1970-01-01
相关资源
最近更新 更多