0

C++ クラスのチェッカーのシミュレーション ゲームに取り組んでいます。私の問題は、チェッカーを保持するリンクされたリストにあります。リストの先頭を除いて、すべてのチェッカーを完全に削除できます。ここや他のウェブサイトを見回しましたが、どこかにメモリリークがあると思います。私はC++にかなり慣れていないので、いろいろいじる以外に実際に何をすべきかわかりません(おそらく、より大きな問題を引き起こすだけです)。以前にここに投稿したことがないので、フォーマットが少しずれていたり、乱雑であったりしたらすみません。手短にしようと思います。まず、リンク リストのノード クラスのスニペットを次に示します。

class CheckerpieceNode 
{
private:
    Checkerpiece *Node;
    CheckerpieceNode *Next;
public:
    CheckerpieceNode(); // sets Node and Next to NULL in .cpp file
    void setNode(Checkerpiece *node);
    void setNext(CheckerpieceNode *next);
    Checkerpiece* getNode();
    CheckerpieceNode* getNext();
}; 

関数は、Checkerpiece.cpp クラスで期待されるように設定されています。コードの使用方法は次のとおりです。私のメインクラスのチェッカーボードオブジェクトによって呼び出されます。

 theCheckerboard.removeChecker(theCheckerboard.findChecker(selector->getCurrentX() + 0, selector->getCurrentY() - VERTICAL_SHIFT, listHead), listHead);

VERTICAL_SHIFT は、チェッカーボード グラフィックがコンソールに表示される方法に関係しています。他のすべてのノード (ヘッドを除く) で完全に機能するため、エラーの原因として除外しました。Selector はチェッカーピース オブジェクトですが、リストの一部ではありません。

Checkerboard クラスの実際の findChecker および removeChecker コードを次に示します。

Checkerpiece* findChecker(int x, int y, CheckerpieceNode* list_head)
{
if(list_head== NULL) return NULL; // do nothing
else
{
    CheckerpieceNode* node = new CheckerpieceNode;
    node = list_head;
    while(node != NULL && node->getNode() != NULL)
    {
        if()// comparison check here, but removed for space
        {
            return node->getNode(); 
            delete node; 
            node = NULL;
        }
        else // traversing
            node = node->getNext();
    }

    return NULL; 
}
}


void removeChecker(Checkerpiece* d_checker, CheckerpieceNode* list_head)
{
if(list_head== NULL) // throw exception
else
{
    CheckerpieceNode *temp = NULL, *previous = NULL;
    Checkerpiece* c_checker= new Checkerpiece;
    temp = list_head;
    while(temp != NULL && temp->getNode() != NULL)
    {
        c_checker= temp->getNode();
        if(d_checker!= c_checker) 
        {
            previous = temp;
            temp = temp->getNext();
        }
        else
        {
            if(temp != list_head)
            {
                previous->setNext(temp->getNext());
                delete temp;
                temp = NULL;
            }
            else if(temp == list_head) // this is where head should get deleted
            {   
                temp = list_head;
                list_head= list_head->getNext();
                delete temp;
                temp = NULL;
            }


            return;
        }
    }
}
}
4

3 に答える 3

0

removeChecker は、list_head の値が過去のものであるため、値を変更できません。メソッドのシグネチャは次のとおりです。

void removeChecker(Checkerpiece* d_checker, CheckerpieceNode** list_head)
// You will need to call this function with &list_head

また

void removeChecker(Checkerpiece* d_checker, CheckerpieceNode* &list_head)
// Calling code does not need to change
于 2013-10-19T01:58:02.547 に答える
0

ああ、あなたはそれを複雑にしています。冗長なチェック、割り当て、不要な変数がたくさんあります (c_checkerメモリ リークも発生します)。

// Write down the various scenarios you can expect first:
// (a) null inputs
// (b) can't find d_checker
// (c) d_checker is in head
// (d) d_checker is elsewhere in the list
void removeChecker(Checkerpiece* d_checker, CheckerpieceNode* list_head) {
   // first sanitize your inputs
   if (d_checker == nullptr || list_head == nullptr) // use nullptr instead of NULL. its a keyword literal of type nullptr_t
       throw exception;

   // You understand that there is a special case for deleting head. Good.
   // Just take care of it once and for all so that you don't check every time in the loop.
   CheckerpieceNode *curr = list_head;

   // take care of deleting head before traversal
   if (d_checker == curr->getNode()) {
       list_head = list_head->next; // update list head
       delete curr; // delete previous head
       return; // we're done
   }

   CheckerpieceNode *prev = curr;
   curr = curr->next;

   // traverse through the list - keep track of previous
   while (curr != nullptr) {
       if (d_checker == curr->getNode()) {
           prev->next = curr->next; 
           delete curr;
           break;    // we're done!
       }

       prev = curr;
       curr = curr->next;
   }
}

それが役立つことを願っています。時間をかけて問題を小さな断片に分解し、考えられるシナリオとそれらをどのように処理するかを理解してから、コードの記述を開始してください。

于 2013-10-19T01:59:44.587 に答える