【问题标题】:One function concatenates *this list with another list, and stores the resulting list in a newed list.Avoiding memory leak一个函数将 *this 列表与另一个列表连接起来,并将结果列表存储在新列表中。避免内存泄漏
【发布时间】:2013-04-17 03:21:24
【问题描述】:
template<typename NODETYPE>
const List<NODETYPE> &List<NODETYPE>::operator =(const List<NODETYPE> &right)
{
    if(&right !=this)
    //ListNode is another class I friended with my list class
    {

        ListNode<NODETYPE> *tempPtr = firstPtr;
        ListNode<NODETYPE> *rightPtr = right.firstPtr;

        if(firstPtr==lastPtr)
        {
            firstPtr = lastPtr = 0;
            delete tempPtr;

            while(rightPtr!=NULL)
            {
                insertAtBack(rightPtr->data);
                rightPtr=rightPtr->nextPtr;
            }
        }
        else
        {
            while(tempPtr!=NULL)
            {
                firstPtr = firstPtr->nextPtr;
                delete tempPtr;
                tempPtr = firstPtr;
            }
            while(rightPtr!=NULL)
            {
                insertAtBack(rightPtr->data);
                rightPtr=rightPtr->nextPtr;
            }
        }
    }
    return *this;
}
template<typename NODETYPE>
List<NODETYPE>& List<NODETYPE>::concatenate(const List<NODETYPE>&right)const
{
    ListNode<NODETYPE>*tempPtr = firstPtr;

我在这里使用了 new 操作符,所以当我返回它时不会调用对象的析构函数。我想创建一个由两个列表组成的全新 List 对象,并将其返回给主函数,同时避免任何内存泄漏。

    List<NODETYPE>*newList = new List;


    while(tempPtr != NULL)
    {
        newList->insertAtBack(tempPtr->data);
        tempPtr = tempPtr->nextPtr;
    }
    tempPtr = right.firstPtr;

    while(tempPtr != NULL)
    {
        newList->insertAtBack(tempPtr->data);
        tempPtr = tempPtr->nextPtr;
    }
    return *newList;
}

如何在不造成内存泄漏的情况下返回 newlist 对象?

template< typename NODETYPE >

void List< NODETYPE >::insertAtBack( const NODETYPE &value )
{
   ListNode< NODETYPE > *newPtr = getNewNode( value ); // new node

   if ( isEmpty() ) // List is empty
      firstPtr = lastPtr = newPtr; // new list has only one node
   else // List is not empty
   {
      lastPtr->nextPtr = newPtr; // update previous last node
      lastPtr = newPtr; // new last node
   } // end else
} // end function insertAtBack

template< typename NODETYPE >
void List< NODETYPE >::insertAtPos( const NODETYPE & value, int pos)
{
    if (pos == 0)
        insertAtFront(value);
    else if (pos < 0)
        cerr << "Trying to insert at invalid list position: " << pos << endl;
    else {
        ListNode< NODETYPE > * ptr = firstPtr;
        for (int i=0; i<pos-1 && ptr != NULL; i++)
            ptr = ptr->nextPtr;
        if (ptr != NULL) {
            ListNode< NODETYPE > *newPtr = getNewNode( value ); // new node
            newPtr->nextPtr = ptr->nextPtr;
            ptr->nextPtr = newPtr;
        }
        else {
            cerr << "Trying to insert at invalid list position." << endl;
        }
    }
}

【问题讨论】:

    标签: c++ list templates


    【解决方案1】:

    如果有人忘记删除从连接返回的对象,就会出现内存泄漏问题。如果您将对列表的引用作为参数,您可以让他们分配列表,并且它将在他们的代码中适当地保留范围。

    本质上不要在函数中分配内存,要求将其传递给函数。

    List<NODETYPE>& List<NODETYPE>::concatenate(const List<NODETYPE> &right, List &newList) const
    

    你仍然可以在最后返回对 newList 的引用,这样函数就可以被链接起来。

    【讨论】:

    • 是的,这绝对有道理。我的老师希望我们创建一个带有一个 List 对象参数的函数,然后该函数将 List 对象参数附加到 *this List 并将其存储在新创建的列表中.不过,你的方式对我来说更有意义。我只是不想使用 main 来释放内存
    • 您不必在 main 函数中使用 new 关键字。您可以只定义 List newList;然后使用 &newList 传递给函数。一旦变量离开作用域,就会调用析构函数。无论如何,如果您的库的用户想要以特殊方式(即内存管理器)分配内存,您不应该在函数中分配内存。
    猜你喜欢
    • 1970-01-01
    • 2018-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-28
    • 1970-01-01
    相关资源
    最近更新 更多