2017-10-03 10 views
0

リンクリストを実装しようとしていますが、完全に失われています。私はその場所全体、特に消去方法を使ってブレークポイントを取得しています。私が消去方法を変更すると、必然的にいくつかのエラーが発生します。ポインタのエラー、eraseメソッドが呼び出されたときにのみ発生するデストラクタの問題などがあります。ここで二重リンクリストの実装

は、私がこれまで持っているものです。

ヘッダファイル:

#pragma once 

class IntList { 
private: 

    class IntNode { 
    public: 
     IntNode(int v, IntNode *pr, IntNode *nx); 
     ~IntNode(); 
     IntNode* previous; 
     IntNode* next; 

     class iterator { 

     public: 
      iterator(IntNode* t); 
      int& operator*(); 
      iterator& operator++(); 
      iterator& operator--(); 
      bool operator!=(iterator other)const; 
     private: 
      IntNode* target; 
     }; 

    private: 
     int value; 
    }; 

    IntNode* head; 
    IntNode* tail; 
    int count; 

public: 

    IntList(); 
    ~IntList(); 
    void push_back(int v); 
    void pop_back(); 
    int size() const { return count; } 
    typedef IntNode::iterator iterator; 
    iterator begin(); 
    iterator end(); 
    //unsigned int size() const; 
    void push_front(int value); 
    bool empty() const; 
    int& front(); 
    int& back(); 
    void clear(); 
    iterator erase(iterator position); 
}; 

が実装:

#include "IntList.h" 
#include <stdexcept> 

IntList::IntList() : head{ nullptr }, tail{ nullptr }, count{ 0 } 
{} 

IntList::~IntList() { 
    while (head) { 
     head = head->next; 
     delete head; 
    } 
} 

void IntList::push_back(int v) { 
    tail = new IntNode{ v, tail, nullptr }; 
    if (!head) { head = tail; } 
    count += 1; 
} 

void IntList::pop_back() { 
    tail = tail->previous; 
    delete tail->next; 
    count -= 1; 
} 

IntList::iterator IntList::begin() 
{ 
    return iterator{ head }; 
} 

IntList::iterator IntList::end() { 
    return iterator{ nullptr }; 
} 

void IntList::push_front(int value) { 
    head = new IntNode{ value, nullptr, head }; 
    if (!tail) { tail = head; } 
    count += 1; 
} 

bool IntList::empty() const{ 
    return (count==0); 
} 

int& IntList::front() { 
    return *begin(); 
} 

int& IntList::back() { 
    return *begin(); 
} 

void IntList::clear() { 
    head = nullptr; 
    tail = nullptr; 
    count = 0; 
} 

IntList::iterator IntList::erase(iterator position) { 

    int midpointL = 0; 

    for (iterator index = begin(); index != position; ++index) { 
     midpointL++; 
    } 

    if (midpointL == 0) { 
     head = head->next; 
    } 
    else if (midpointL == count) { 
     tail = tail->previous; 
    } 
    else { 

     // Move head to get a reference to the component that needs to be deleted 
     for (int i = 0; i < midpointL; i++) { 
      head = head->next; 
     } 

     // Change the previous and next pointers to point to each other 
     (head->previous)->next = (head->next); 
     (head->next)->previous = (head->previous); 

     for (int i = midpointL-1; i > 0; i++) { 
      head = head->previous; 
     } 

    } 

    count-=1; 

    return position; 
} 


IntList::IntNode::IntNode(int v, IntNode * pr, IntNode * nx) 
    : previous{ pr }, next{ nx }, value{ v } 
{ 
    if (previous) { previous->next = this; } 
    if (next) { next->previous = this; } 
} 

IntList::IntNode::~IntNode() { 
    if (previous) previous->next = next; 
    if (next) next->previous = previous; 
} 

IntList::IntNode::iterator::iterator(IntNode* t) 
    : target{ t } 
{} 

int& IntList::IntNode::iterator::operator*() { 
    if (!target) { throw std::runtime_error{ "Deferenced sentinel iterator." }; } 
    return target->value; 
} 

IntList::IntNode::iterator& IntList::IntNode::iterator::operator++() 
{ 
    if (target) { target = target->next; } 
    return *this; 
} 

IntList::IntNode::iterator& IntList::IntNode::iterator::operator--() 
{ 
    if (target) { target = target->previous; } 
    return *this; 
} 

bool IntList::IntNode::iterator::operator!=(iterator other)const 
{ 
    return (!(target == other.target)); 
} 

誰もが正しい方向に私を指す助けてもらえますか?

ありがとうございます!

+0

1)[STD ::リスト](http://en.cppreference.com/w/cpp/container/list)がすでに存在している、楽しみを持っています。 2)実際には、代わりに[std :: vector](http://en.cppreference.com/w/cpp/container/vector)を使用したいと思うかもしれません(実際のところ、リンクされたリストは恐ろしい*深刻なパフォーマンスを持つデータ構造)。 –

+0

私は彼が練習のためにこれをやっていると思います。また、リンクされたリストには、リストからの一定時間の挿入/削除が必要なときなど(時間予測可能性が絶対に重要なリアルタイムコンピューティングのような)独自の使い方があります。 – BlooB

+0

"int&IntList :: back(){ return * begin(); } " - それはちょうど間違って見える*。なぜyould 'end()'を返す 'begin()'?それだけでは意味がありません。 –

答えて

1

のは、ここで簡単に復習のようなものを作ってみましょう:

IntList::~IntList() { 
    while (head) { 
     head = head->next; 
     delete head; 
    } 
} 

あなたが代わりに行う必要があります。

IntList::~IntList() { 
    while (head) { 
     IntNode* newHead = head->next; 
     delete head; 
     head = newHead; 
    } 
} 

あなたが「次の」オブジェクトを削除され、その後、あなたがへのアクセスを取得しようとしているとして、それは次の反復で。

void IntList::pop_back() { 
    tail = tail->previous; 
    delete tail->next; 
    count -= 1; 
} 

尾がnullの場合、または頭を指している場合ここでは、(空の条件は何ですか?)...多分count!=0をチェックされていませんか?場合にはあなたが

IntList::iterator IntList::end() { 
    return iterator{ nullptr }; 
} 

存在しない次のノードを削除することができます。.. endはnullですか?あなたの尻尾はebdでなければなりません。

これは始まりではありません。

void IntList::clear() { 
    head = nullptr; 
    tail = nullptr; 
    count = 0; 
} 

clearは、リスト内のすべてのオブジェクトを解放する必要があります。ここでゴミを生成しています(リーク)。

私はここで停止しました。申し訳ありませんが、ちょうどコーヒーブレークです。しかし、あなたが注意深く見る必要があります。 * NULLポインタの使用 *無効なポインタを使用していないために *有料の注意を必要としないとき(のようなhead->previous->next私はどこかで見た)あなたは、あなたのコードを確認する必要が

あなたのノードリストの項目を削除し、一気飲み。それらの最初のヒントがあなたの学習プロセスを通じてあなたを助けてくれることを願っています。

は サント

関連する問題