在两个层迭代器中超载 产生奇怪的错误

overloading ++ in two layer iterator produces strange bug

本文关键字:超载 错误 中超 迭代器 两个      更新时间:2023-10-16

我将以下C 代码编写为迭代对象向量的向量。我想迭代向量向量中的每个对象。下面的代码有效,但我不明白它具有一个特殊性。

行" int type_size = types-> size();"行是Iterator.hpp中使用的黑客。我真的不太了解该语言,所以我不知道我是否找到了编译器错误,还是我的代码中的错误。不需要变量" type_size"。它用于两行

第一行:

while(s<types_size && (s<0 || (*types)[s]->size()==0 || object==&( ((*types)[s])->end()))){

第二行:

if(s<types_size){

如果" type_size"被第一行中的" type-> size()"替换,则代码在运行时会出现故障。进行相同的替换,但仅在第二行中不会导致SEG故障。我不明白发生了什么。对本代码其余部分的任何评论将不胜感激。

#ifndef _iterator_hpp_
#define _iterator_hpp_
#include <vector>
using namespace std;
typedef double Object;
typedef vector<Object> ObjectVector;
class Region{
public:
    vector<ObjectVector*> types;
};
class ObjectIterator{
private:
    int s;
    vector<ObjectVector*> *types;
protected:
public:
    Object *object;
    bool finished;
    ObjectIterator operator++(){
        if (s>=0) object++; // increments to next object
        int types_size=types->size();    // this is a hack that fixes a seg fault (compiler bug??)
        // *types is a vector<ObjectVector*>. (*types)[s] is the "sth" ObjectVector*.
        // &(*iterator) gives a pointer to the object pointed to by iterator.
        //((*types)[s])->end()) is an iterator that points past the end of
        // the ObjectVector* ((*types)[s])->end())
        while(s<types_size && (s<0 || (*types)[s]->size()==0 || object==&(*      ((*types)[s])->end()))){
            //need to increment to next non-empty types
            s++;
            if(s<types_size){
                object=&((*(*types)[s])[0]);
            }else{finished=true;}
        }
        return (*this);
    }
    /*---------------------constructor--------------------------------------------------------
      start with s=-1 and increment to first object */
    ObjectIterator(vector<ObjectVector*> *typesarg):finished(false) {
        types=typesarg;s=-1;++(*this);
    };
};
#endif

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

// it.cpp
//  g++ it.pp 
#include <iostream>
#include <vector>
#include "iterator.hpp"
using namespace std;
int num_types=3;
int main(){
  Region region;
  int num_objects[num_types];
  num_objects[0]=1;
  num_objects[1]=3;
  num_objects[2]=5;
  // create an ObjectList for each type 

  for(int s=0;s<num_types;s++){
    ObjectVector *objectlist = new ObjectVector;
    for(int i=0;i<num_objects[s];i++){
      objectlist->push_back((double)2*(i+1)*(s+1));
    }
    region.types.push_back(objectlist);
  }
  cout <<"types.size="<< region.types.size()<<endl;
  for(ObjectIterator OI(&region.types); !OI.finished ; ++OI)
    {
      cout <<*(OI.object)<<endl;
    }

}

size()返回一个未签名的整数,因此:

while(s<types->size() 

如果s为-1(其初始值),则行为不会相同。-1变成一个大型无符号整数,比较是错误的。有关更多信息,请参见签名/未签名的比较。