2016-03-25 3 views
1

私は並べ替えられたキューの二重リンクされたリストの実装を使用するプログラムで作業しています。このファイルは、メモリリークが発生する唯一のファイルです。C++プログラムでメモリリークを防止するにはどうすればよいですか?

また、私はヘッダーを編集することはできません。

私はあなたがすべてのオブジェクトがnewを使用して作成し削除する必要がありますメモリリークを防ぐために、それを理解。

void PriorityQ::Enqueue(Message msg) 
{ 
Priorities P = msg.GetPriority(); 
Node* Location = frontPtr; 
Node* PrevLocation = frontPtr; 
Node* NewNode = new Node; 
NewNode->data = msg; 




    if (IsFull()) 
    throw FullPQ(); 
    else if (count == 0) 
    { 
     NewNode->previousPtr = NULL; 
     NewNode->nextPtr = NULL; 
     count++; 
     frontPtr = NewNode; 
     rearPtr = NewNode; 
    } 
    else 
    { 
     Priorities LP = Location->data.GetPriority();   
     while(LP >= P) 
     { 
      if(Location == NULL) 
       break; 

      PrevLocation = Location; 
      Location = Location->nextPtr; 

      if(Location != NULL) 
       LP = Location->data.GetPriority(); 

     }//end line 50 while 

      if(Location == NULL) 
       { 
        NewNode->previousPtr = PrevLocation; 
        NewNode->nextPtr = Location; 
        PrevLocation->nextPtr = NewNode; 
        rearPtr = NewNode; 
        count++; 

       } 
      else 
       { 
        PrevLocation = Location->previousPtr; 
        NewNode->previousPtr = PrevLocation; 
        NewNode->nextPtr = Location; 

        if(PrevLocation == NULL) 
        { 
         Location->previousPtr = NewNode; 
         count++;  
         frontPtr = NewNode;       
        } 
        else 
        { 
         PrevLocation->nextPtr = NewNode; 
         Location->previousPtr = NewNode; 
         count++;          
        } 
       }// end line 73 else 

    } //end Line 48 else 
delete NewNode; 
}//end Enqueue() Function 

私はdeleteを置く場合、私は、セグメンテーションエラーにEnqueue(Message msg)関数が呼び出された次の時間を取得し、そして:

私の問題は、私はそうのように私のEnqueue(Message msg)関数の最後にdeleteを配置する場合ということです私のデストラクタで:

PriorityQ::~PriorityQ() 
{ 
MakeEmpty(); 

delete NewNode; 

} 

それは私にこのエラーpriorityq.cpp [Error] 'NewNode' was not declared in this scope

のでを与えます私の質問は、どのように私はそれらを作成した直後にキュー内のオブジェクトを割り当て解除せずに自分のコードでメモリリークを防ぐことができますです。

ここにフルファイルがあります。

#include "priorityq.h" 


PriorityQ::PriorityQ() 
{ 
    frontPtr = NULL; 
    rearPtr = NULL; 
    count = 0; 

} 

PriorityQ::~PriorityQ() 
{ 
    MakeEmpty(); 

    delete NewNode; 

} 

void PriorityQ::MakeEmpty() 
{ 
    frontPtr = NULL; 
    rearPtr = NULL; 
    count = 0; 
} 

void PriorityQ::Enqueue(Message msg) 
{ 
    Priorities P = msg.GetPriority(); 
    Node* Location = frontPtr; 
    Node* PrevLocation = frontPtr; 
    Node* NewNode = new Node; 
    NewNode->data = msg; 




     if (IsFull()) 
     throw FullPQ(); 
    else if (count == 0) 
    { 
     NewNode->previousPtr = NULL; 
     NewNode->nextPtr = NULL; 
     count++; 
     frontPtr = NewNode; 
     rearPtr = NewNode; 
    } 
    else 
    { 
     Priorities LP = Location->data.GetPriority();   
     while(LP >= P) 
     { 
      if(Location == NULL) 
       break; 

      PrevLocation = Location; 
      Location = Location->nextPtr; 

      if(Location != NULL) 
       LP = Location->data.GetPriority(); 

     }//end line 50 while 

      if(Location == NULL) 
       { 
        NewNode->previousPtr = PrevLocation; 
        NewNode->nextPtr = Location; 
        PrevLocation->nextPtr = NewNode; 
        rearPtr = NewNode; 
        count++; 

       } 
      else 
       { 
        PrevLocation = Location->previousPtr; 
        NewNode->previousPtr = PrevLocation; 
        NewNode->nextPtr = Location; 

        if(PrevLocation == NULL) 
        { 
         Location->previousPtr = NewNode; 
         count++;  
         frontPtr = NewNode;       
        } 
        else 
        { 
         PrevLocation->nextPtr = NewNode; 
         Location->previousPtr = NewNode; 
         count++;          
        } 
       }// end line 73 else 

    } //end Line 48 else 
delete NewNode; 
}//end line 27 Enqueue() Function 

void PriorityQ::Dequeue() 
{ 
    if(IsEmpty()) 
    { 
     EmptyPQ Empty; 
     throw Empty; 
    } 

Node* Location = frontPtr; 
frontPtr = frontPtr->nextPtr; 
Location->nextPtr = NULL; 

if(frontPtr != NULL) 
{ 
    frontPtr->previousPtr = NULL; 
} 
else 
{ 
    MakeEmpty(); 
} 
if(count != 0) 
    count--; 

} 

void PriorityQ::Purge(Priorities p) 
{ 
if(IsEmpty()) 
{ 
    EmptyPQ Empty; 
    throw Empty; 
} 

Node* PurgePtr = frontPtr; 
Priorities c = PurgePtr->data.GetPriority(); 
for(int j = 1; j < count; j++) 
{ 
    if(c == p) 
    { 
     if(PurgePtr->previousPtr == NULL) 
      Dequeue(); 
     else if(PurgePtr->nextPtr == NULL) 
      PurgePtr->previousPtr->nextPtr = NULL; 
     else 
     { 
      PurgePtr->previousPtr->nextPtr = PurgePtr->nextPtr; 
      PurgePtr->nextPtr->previousPtr = PurgePtr->previousPtr; 
     } 
    }// end line 130 if 
    else 
    { 
     PurgePtr = PurgePtr->nextPtr; 
     c = PurgePtr->data.GetPriority(); 

    } 
}// end line 127 for 

} 

Message PriorityQ::Front() const 
{ 
    if(IsEmpty()) 
     throw EmptyPQ(); 
    return frontPtr->data; 
} 

Message PriorityQ::Rear() const 
{ 
    if(IsEmpty()) 
     throw EmptyPQ(); 
    return rearPtr->data; 
} 

Message PriorityQ::Peek(int n) const 
{ 
    if(n <= (count - 1)) 
    { 
     Node* PeekPtr = frontPtr; 

     for(int j = 0; j < n; j++) 
     { 
      PeekPtr = PeekPtr->nextPtr; 
     } 

     return PeekPtr->data; 

    } 
    else 
     throw InvalidPeekPQ(); 


} 

bool PriorityQ::IsFull() const 
{ 
    if(count < 501) 
     return false; 
    else 
     return true; 
} 

bool PriorityQ::IsEmpty() const 
{ 
    if(count == 0 && frontPtr == NULL) 
     return true; 
    else 
     return false; 
} 

int PriorityQ::Size() const 
{ 

    return count; 
} 

答えて

1

問題がNewNodeでは、方法void Priority::Enqueueのローカルポインタです。したがって、他の方法からアクセスすることはできません。

方法仕上げNewNodeを排除し、あなたがそれにアクセスすることはできませんです。

+0

これは確かに問題ですが、多くの問題があります。たとえば、 'IsFull()'が 'Enqueue'を' throw'にした場合、 'newNode'はリストに追加されず、' delete'dも追加されません。とにかく、デストラクタはリストを反復する必要があります。他に関連のないバグがあります。 'Dequeue'は、最後の要素を抽出するときに' rearPtr'を 'nullptr'に設定しません。 –

+0

@Alberto私は新しいノードの作成についてどうやってお勧めしますか? – Versanator

+0

今、それはそれを行います。問題は、最後の命令 'delete NewNode'で新しいノードを解放することです。メソッド 'void Priority :: Dequeue'で" Node "を解放し、デストラクターで明らかに必要ならば、 – B026

関連する問題