0

リンクされたリストと、リンクされたリスト内のいくつかのノードへのポインターのベクトルを使用して、テンプレート クラスのコードを作成しています。コードが醜いのは、うまくいくと思ったものを書き、エラー メッセージの修正に重点を置いて修正しただけだからです。

項目を挿入するたびに position メソッドで正しい位置を見つけるため、リスト (したがって、ベクトルも) はソートされたままになります。

最初はエラーが多かったのですが、試行錯誤の末に修正することができました。これでコンパイルできますが、このテンプレート クラスが正常に動作するかどうかをメイン メソッドでテストすると、エラー メッセージがスローされます。

「std::out_of_range」のインスタンスをスローした後に呼び出される終了

what(): vector::_M_range_check

中止 (コアダンプ)

std::out_of_range が何であるかは知っていますが、このエラーが発生する理由は本当にわかりません。ベクトルの要素にアクセスする私のコードには多くの部分さえありません。

以下はメイン メソッドをテストするためのコードで、次はテンプレート クラス (およびネストされたイテレータ クラス) の定義です。

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>
#include <vector>
#include "ValliHN.h"
using namespace std;

int main() {
    Valli<string> valli;

    valli.insert("K");
valli.insert("H");
valli.insert("N");
valli.insert("H");
valli.insert("J");

for (Valli<string>::iterator i = valli.begin(); i != valli.end(); i++)
    cout << *i << endl;

return 0;
}

テンプレートクラス

#include"DList.h"
#include<iostream>
#include<vector>
#include<algorithm>
#include<cstdlib>

using std::cout;
using std::endl;
using std::cerr;
using std::vector;

template<typename I>
class Valli {

vector< DNode<I>* > va;
DList<I> lli;
size_t ratio;
friend class iterator;
friend class DList<I>;

public: 

class iterator {

  typename DList<I>::iterator list_iter;
  iterator(DNode<I>* node) 
   : list_iter(typename DList<I>::iterator(node)) { }
  friend class Valli<I>;
  friend class DList<I>;

public:
     I& operator*() const {
        return *list_iter;
     }

     iterator& operator++() {
        ++list_iter;
        return *this;
     }

     iterator operator++(int) {
        iterator* ret = this;
        ++list_iter;
        return *ret;
     }

     iterator& operator--() {
        --list_iter;
        return *this;
     }

     iterator operator--(int) {
        typename DList<I>::iterator ret = list_iter;
        --list_iter;
        return ret;
     }

     bool operator==(const iterator& rhs) const {
        return list_iter == rhs.list_iter;
     }

     bool operator!=(const iterator& rhs) const {
        return list_iter != rhs.list_iter;
     }

     DNode<I>* returnCurr() const {
        return list_iter.returnCurr();
     }
};

explicit Valli<I>(size_t ratio=4)
 : ratio(ratio),
  lli(DList<I>()),
  va(vector< DNode<I>* >()) { }

//   Valli<I>()
//    : Valli<I>(4) { }

~Valli<I>() {
//      delete[] va;
//      delete lli;
}

iterator insert(const I& item) {
   iterator pos = position(va, item);
   lli.insert(pos.returnCurr(), item);
   refresh(4);
   return --pos;
}

iterator find(const I& item) const {
  iterator start = iterator(va.at(binsearch(va, item)));
  iterator end = iterator(va.at(binsearch(va, item)+1));
  while(start != end) {
     if(*start = item) {
        return start;
     }
     else {
        ++start;
     }
  }
}
//   void erase(iterator itr) {}

iterator begin() const {
   lli.begin();
}

iterator end() const {
   lli.end();
}

private:
int binsearch(const vector< DNode<I>* > vec, const I& item) const {
  int left = 0;
  int right = vec.size()-1;
  while(left <= right) {
     int mid = (left+right)/2;
     iterator iter = iterator(vec.at(mid));
     if(item < *iter) {
        right = mid-1;
     }
     else if(item == *iter) {
        return mid;
     }
     else {
        left = mid+1;
     }
  }
  return left;
 }

iterator position(const vector< DNode<I>* > vec, const I& item) const {
  iterator start = iterator(vec.at(binsearch(vec, item)));
  iterator end = iterator(vec.at(binsearch(vec, item)+1));
  while(start != end) {
     if(*start < item) {
        ++start;
     }
     else {
        return start;
     }
  }

}

void refresh(size_t newRatio) {
  iterator iter = begin();
  int count = 0;
  va.clear();
  while(iter!=end()) {
     if(count % newRatio == 0) {
        va.push_back(iter.returnCurr());
     }
     //push_backing the last node - to be added
     iter++;
     count++;
  }
}

};

クラス DList.h は、標準のライブラリ リスト クラスに非常に似ています。私のコードで問題を確認できますか? また、優れたプログラミング手法とコーディング方向の実装の両方に関して、私のコード全体が良いか悪いか教えていただけますか?

どうもありがとうございました!

4

1 に答える 1

1

最初の挿入で範囲外のベクトルがあるように見えます。insert は、binsearch を呼び出す position を呼び出します。ベクトルが空であるため、binsearch は 0 を返し、位置は vector.at(0) (および vector.at(1)) を呼び出します。ベクトルが空であるため、これらは両方とも範囲外エラーです。

コードをじっと見ているだけなので、間違っている可能性があります。本当にデバッガを使用して、問題が発生した場所を正確に見つける必要があります。

于 2013-03-28T08:04:27.150 に答える