0

我正在为带有链表和指向链表中某些节点的指针向量的模板类编写代码。代码很丑,因为我只是写了我认为可能有用的东西,并更正了它,专注于修复错误消息。

列表(相应地,向量也是)保持排序,因为它每次插入项目时都会使用 position 方法找到正确的位置。

最初,我有很多错误,经过大量尝试后我能够修复它们。现在它可以编译了,但是当我用 main 方法测试它时,如果这个模板类工作正常,它会抛出一条错误消息:

在抛出 'std::out_of_range' 的实例后调用终止

什么():向量::_M_range_check

中止(核心转储)

我知道 std::out_of_range 是什么,但我真的不明白为什么会发生这个错误。我的代码中甚至没有很多部分可以访问向量的元素。

下面是测试 main 方法的代码,接下来是我的模板类(和嵌套迭代器类)的定义。

#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。binsearch 返回 0,因为向量为空,然后位置调用 vector.at(0)(和 vector.at(1))。这两个都是超出范围的错误,因为向量是空的。

我只是盯着代码,所以我可能犯了一个错误。真的,您应该使用调试器,并找出问题发生的确切位置。

于 2013-03-28T08:04:27.150 回答