2016-05-13 14 views
-1

リストから要素を削除すると、この問題が発生します。ここでエラーSmartPointerのリスト内のEXC_BAD_ACCESS

私list.h:

AwesomeList<int> list = AwesomeList<int>(); 
list.add(1); 
list.add(2); 
list.add(3); 
for (int i = 0; i < list.getSize(); i++) 
    qDebug() <<*(list.at(i)) <<" "; 

list.remove(-1); 
for (int i = 0; i < list.getSize(); i++) 
    qDebug() <<*(list.at(i)) <<" "; 

list.remove(2); 
for (int i = 0; i < list.getSize(); i++) 
    qDebug() <<*(list.at(i)) <<" "; 

list.replace(0, 5); 
qDebug() <<"Replace in posizione 0"; 
auto cit = list.begin(); 
for (; cit != list.end(); cit++) 
    qDebug() <<*(*cit) <<" "; 

qDebug() <<"Size"; 
qDebug() <<list.getSize() <<endl; 

これはエラーが表示されます行です:

  • AwesomeListを:: Nodo

    class AwesomeList { 
    friend class Iteratore; 
    private: 
    class Nodo; 
    
    class SmartPointer { 
    public: 
        Nodo* punt; 
    
        SmartPointer(Nodo* n = 0): punt(n) {} 
        SmartPointer(const SmartPointer& ptr): punt(ptr.punt) {} 
        ~SmartPointer() { 
         delete punt; 
        } 
    
        SmartPointer& operator=(const SmartPointer& ptr) { 
         if (this != &ptr) { 
          delete punt; 
          punt = ptr.punt; 
         } 
         return *this; 
        } 
        bool operator==(const SmartPointer& ptr) const { 
         return ptr.punt == punt; 
        } 
        bool operator!=(const SmartPointer& ptr) const { 
         return ptr.punt != punt; 
        } 
        Nodo* operator->() const { 
         return punt; 
        } 
        Nodo& operator*() const { 
         return *punt; 
        } 
    }; 
    
    class Nodo { 
    public: 
        T* value; 
        SmartPointer next; 
    
        Nodo(T* t = T(), const SmartPointer& ptr = SmartPointer()): value(t), next(ptr) {} 
    }; 
    
    SmartPointer head; 
    SmartPointer tail; 
    
    public: 
    class Iteratore{ 
        friend class AwesomeList; 
    private: 
        AwesomeList::SmartPointer punt; 
    public: 
        bool operator==(const Iteratore& it) const { 
         return it.punt == punt; 
        } 
        bool operator!=(const Iteratore& it) const { 
         return it.punt != punt; 
        } 
        Iteratore& operator++() { 
         if(punt != 0) punt = punt->next; 
         return *this; 
        } 
        Iteratore& operator++(int) { 
         if(punt != 0) punt = punt->next; 
         return *this; 
        } 
        T* operator*() const { 
         if (punt != 0) return punt->value; 
        } 
    }; 
    
    AwesomeList(const SmartPointer& ptr = 0): head(ptr), tail(0) { 
        if (head != 0) { 
         SmartPointer p = head; 
         while (p != 0) 
          p = p->next; 
         tail = p; 
        } 
    } 
    AwesomeList(const AwesomeList& list): head(list.head), tail(list.tail) {} 
    
    AwesomeList& operator=(const AwesomeList& list) { 
        head = list.head; 
        tail = list.tail; 
    } 
    
    int getSize() const { 
        int count = 0; 
        SmartPointer p = head; 
        while (p != 0) { 
         p = p->next; 
         count++; 
        } 
        return count; 
    } 
    bool isEmpty() const { 
        return getSize() == 0; 
    } 
    T* at(int pos) const { 
        if (pos > -1 && pos < getSize()) { 
         SmartPointer p = head; 
         while (pos--) { 
          p = p->next; 
         } 
         return p->value; 
        } else return 0; 
    } 
    void add(const T& t) { 
        if (head == 0) { 
         head = SmartPointer(new Nodo(&(const_cast<T&>(t)))); 
         tail = head; 
        } else { 
         tail->next = SmartPointer(new Nodo(&(const_cast<T&>(t)))); 
         tail = tail->next; 
        } 
    } 
    void remove(int pos) { 
        if (pos > -1 && pos < getSize()) { 
         SmartPointer newHead = head; 
         SmartPointer p = newHead; 
         head = 0; 
         while (pos--) { 
          add(*p->value); 
          p = p->next; 
         } 
         p = p->next; 
         while (p != 0) { 
          add(*p->value); 
          p = p->next; 
         } 
        } 
    } 
    void replace(int pos, T* t) { 
        if (pos > -1 && pos < getSize()) { 
         SmartPointer p = head; 
         while (pos--) 
          p = p->next; 
         p->value = t; 
        } 
    } 
    void replace(int pos, const T& t) { 
        if (pos > -1 && pos < getSize()) { 
         SmartPointer p = head; 
         while (pos--) 
          p = p->next; 
         T& t_obj = const_cast<T&>(t); 
         p->value = &t_obj; 
        } 
    } 
    
    Iteratore begin() const { 
        Iteratore it; 
        it.punt = head; 
        return it; 
    } 
    Iteratore end() const { 
        Iteratore it; 
        it.punt = 0; 
        return it; 
    } 
    T* operator[](const Iteratore& it) const { 
        return it.punt->value; 
    } 
    }; 
    

    この私が行った試験は、次のとおりです。 :〜Nodo()+ 16(awesomelist.h:8)

  • AwesomeList :: SmartPointer ::〜SmartPointer ()+ 42(awesomelist.h:21)
  • AwesomeList :: SmartPointer ::〜SmartPointer()+ 21(awesomelist.h:22)

すべてのヘルプは感謝です。ありがとう!

UPDATE

私はこのようなSmartPointerとNodoクラスを変更する私の問題を解決しました。申し訳ありません

SmartPointer(Nodo* n = 0): punt(n) { 
     if (punt) punt->references++; 
    } 
    SmartPointer(const SmartPointer& ptr): punt(ptr.punt) { 
     if (punt) punt->references++; 
    } 
    ~SmartPointer() { 
     if (punt) { 
      punt->references--; 
      if (punt->references == 0) delete punt; 
     } 
    } 

    SmartPointer& operator=(const SmartPointer& ptr) { 
     if (this != &ptr) { 
      Nodo* n = punt; 
      punt = ptr.punt; 
      if (punt) punt->references++; 
      if (n) { 
       n->references--; 
       if (n->references == 0) delete n; 
      } 
     } 
     return *this; 
    } 
    bool operator==(const SmartPointer& ptr) const { 
     return ptr.punt == punt; 
    } 
    bool operator!=(const SmartPointer& ptr) const { 
     return ptr.punt != punt; 
    } 
    Nodo* operator->() const { 
     return punt; 
    } 
    Nodo& operator*() const { 
     return *punt; 
    } 
}; 

class Nodo { 
public: 
    T* value; 
    SmartPointer next; 
    int references; 

    Nodo(T* t = T(), const SmartPointer& ptr = SmartPointer()): value(t), next(ptr), references(0) {} 
}; 
+0

エラーリストに実際にエラーの内容がリストされていません。 – vu1p3n0x

+0

エラーはEXC_BAD_ACCESSです。 – Daniele

+0

私の友人、私はあなたが私たちをだまそうとしていると思います。 'SmartPointer head;は' SmartPointer'の前方宣言だけではコンパイルできません。 SmartPointerをインスタンス化するには、 'SmartPointer'の完全な定義が必要です。 – user4581301

答えて

1

が、私はあなたのSmartPointerクラスの下の割合を理解していません。

コンストラクタでNododeleteへのポインタを持ちます。良い。

しかし、私は間違っていないよ場合

(1)あなたはコピーコンストラクタとSmartPointerを作成するとき、あなたはあなたが同じ値を持つpuntを持つ2つのオブジェクトを持っているので、コピーしたSmartPointerからポインタをコピーします。 2つのオブジェクトを破壊すると、deleteを同じポインタに2回呼び出します。これは、プログラムがクラッシュすることができます

あなたがoperator=を呼び出すとき(2)、あなたはadd()

を見て、コピーコンストラクタはなく、また、あなたが昔の尖った値の例により、

を削除しないと同じ問題を抱えています

head = SmartPointer(new Nodo(&(const_cast<T&>(t)))); 
    tail = head; 

で初期化する一時的なSmartPointerオブジェクトを作成します。次に、この一時的なオブジェクトをheadにコピーします。したがって、headとテンポラリオブジェクトの両方に同じNULLでないポインタが格納されています。今すぐ一時オブジェクトが破棄されるので、puntが指し示すメモリは削除されますが、head(彼のpunt)は削除されたメモリ領域を指し続けます。今度はheadtailにコピーし、同じ削除された領域を指しているheadtailの両方を持っています。この場合

他のケースを見

tail->next = SmartPointer(new Nodo(&(const_cast<T&>(t)))); 
    tail = tail->next; 

tail->next(および削除された領域に、カウントしているtakeポイントを取る)それを削除し、一時的なオブジェクトからポインタを受け取ります。したがって、削除された領域にすぐに削除されるポインタを書き込むことになります。

これはどれくらい危険なのかがはっきりしていることを希望します。

提案:再設計SmartPointerクラス。

p.s .:申し訳ありませんが、私の悪い英語です。

+0

あなたは非常にクリアされています。ありがとう!私のプライベートフィールドSmartPointer *ヘッドを使用して、次にヘッド=新しいSmartPointer(...)と書いて、私の問題を解決できるかと思いますか? – Daniele

+0

しばらくその論理を考えてください。スマートポインタへの未処理のポインタを作成します。これは、スマートポインタのポイントを破ります。マックスは正しいです。あなたは 'SmartPointer'を再実装し、それをルールに準拠させる必要があります(http://en.cppreference.com/w/cpp/language/rule_of_three)、そして[move semanticsを使う](http:// stackoverflow .com/questions/3106110/what-are-move-semantics)。別の方法として、 'SmartPointer'の代わりに' 'std :: unique_ptr'(http://en.cppreference.com/w/cpp/memory/unique_ptr)を使用する方法があります。 – user4581301

+0

はい、そうです。なにか提案を? PS:コードを正しい演算子で更新しました=。 – Daniele

関連する問題