【问题标题】:vector iterator incompatible c++向量迭代器不兼容 C++
【发布时间】:2015-02-17 15:51:46
【问题描述】:

我已经搜索了整个 stackoverflow,但似乎无法找到我正在寻找的东西,所以这里是.. 我有 2 个自定义类,一个在第二个中使用,当我尝试对第二个类进行排序时。它本质上是第一个类的向量,它会引发错误:-消息 0x010c3e18“向量迭代器不兼容”const wchar_t *at vc\include\vector 第 238 行 .. 这是我的代码:

#include <iostream>
#include <conio.h>
#include <cmath>
#include <string>
#include <vector>
#include <fstream>
#include <algorithm>

using namespace std;

class cityPhone {
private: 
    string cityName;
    string cityCode;
public:
 void setCode(string code){
    cityCode=code;
}
 void setName(string name){
    cityName=name;
}
 cityPhone(){
    cityName="Varna";
    cityCode="0888123123";
}
 cityPhone(string name, string code){
    cityName=name;
    cityCode=code;
}
 string getCity(){
return cityName;    
}
 string getCode(){
    return cityCode;
}
};

//struct {               //ive used these 2 also and still it doesnt work
//        bool operator()(cityPhone a, cityPhone b)
//        {   
//            if (a.getCity().compare(b.getCity())>0)return true;
//  return false;
//        }   
//    } cmpCity;
// struct {
//        bool operator()(cityPhone a, cityPhone b)
//        {   
//           if (a.getCode().compare(b.getCode())>0)return true;
//  return false;
//        }   
//    } cmpCode;

bool cmpCity(cityPhone a, cityPhone b) // i'm using these 2 in the sorting method
        {   
            if (a.getCity().compare(b.getCity())>0)return true;
    return false;
        }   


bool cmpCode(cityPhone a, cityPhone b)
        {   
           if (a.getCode().compare(b.getCode())>0)return true;
    return false;
}

 class phoneDirectory {
 private :
     vector<cityPhone> data;
 public:
     phoneDirectory (string path){
        read(path); 
    }
     phoneDirectory (){
        data=vector<cityPhone>();   
    }

   void read(string path){
        cout<<endl;
        try {
string line;
  ifstream myfile (path);
  cityPhone bla = cityPhone();
  if (myfile.is_open())
  {
    while ( getline (myfile,line) )
    {
        try{
      bla = cityPhone(line.substr(0,line.find_first_of(" ")),line.substr(line.find_first_of(" ")+1));
      data.push_back(bla);
        }
        catch(exception){ }
    }
    myfile.close();
  }

  else cout << "Unable to open file"; 
        } catch (exception) {}
}

   void addCityPhone(string city,string phone){
       try{
   data.push_back(cityPhone(city,phone)); 
       }
       catch(exception){
       cout<<"Error adding item "<<endl;
       }
   }

   void delCityPhone(int index){
       try{
   vector<cityPhone>::iterator p=data.begin();
   p+=index;
   data.erase(p);
       } 
       catch(exception){
       cout<<"Error deleting item with index "+index<<endl;
       }
   }

      cityPhone getCityPhone(unsigned index){
       try{
   vector<cityPhone>::iterator p=data.begin();
   p+=index;
   return *p;
       }
       catch(exception){
       cout<<"Error deleting item with index "+index<<endl;
       return cityPhone();
       }
   }

      vector<cityPhone> getData(){
      return data;
      }

   void phoneChange(string city, string newPhone){
   try{
       int i=0;
       vector<cityPhone>::iterator p=data.begin();
       for(p=data.begin();p<data.end();p++,i++){
       if (getCityPhone(i).getCity().compare(city)==0){
           string oldPhone = getCityPhone(i).getCode();
           getCityPhone(i).setCode(newPhone);
           cout<<"Phone of city "+city + " was changed from "+oldPhone + " to " + newPhone<<endl;
           return;
       }
       cout<<"No such city exists!\n";
       }
   }
   catch(exception){
   cout<<"Error changing phone"<<endl;
        }
   }

    friend istream& operator>>(ostream& out,phoneDirectory a);
    friend ostream& operator<<(ostream& out,phoneDirectory a);
 };

istream& operator>>(istream& in,phoneDirectory& a){
    string city,phone;
in >> city >> phone;
a.addCityPhone(city,phone);
return in;
}

ostream& operator<<(ostream &out, cityPhone a){
return out << a.getCity()  <<" " << a.getCode() <<endl;
}

       void sortByCity(phoneDirectory a){//with these two i try to sort
           vector<cityPhone>::iterator p=a.getData().begin();
           vector<cityPhone>::iterator q=a.getData().end();
        std::sort(p,a.getData().end(),cmpCity);
       }

       void sortByCode(phoneDirectory a){
           vector<cityPhone>::iterator p=a.getData().begin();
           vector<cityPhone>::iterator q=a.getData().end();
        std::sort(p,q,cmpCode);//i've tried with std::sort(a.getData().begin(),a.getData().end(),cmpCode) still no effect
       }

 //bool wayToSortCity (cityPhone a, cityPhone b){        //i've tryed also with these , still no effect
 //if (a.getCity().compare(b.getCity())>0)return true;
    //return false;
 //}

 // bool wayToSortCode (cityPhone a, cityPhone b){
 //if (a.getCode().compare(b.getCode())>0)return true;
    //return false;
 //}

int main()
{

    phoneDirectory test("C:\\t.txt");
    sortByCity(test);//here it crashes

for(unsigned i=0;i<test.getData().size();i++)
      cout<<test.getCityPhone(i);

    cin>>test;
    //test.sortBy(1);

    system("pause");
    return 0;
}

【问题讨论】:

  • 请显示 completeunedited 错误输出。并在您的代码中标出错误所在的位置。
  • 在修复了几个小问题(但很明显)后,我无法重现您的错误。

标签: c++ sorting vector stl iterator


【解决方案1】:

问题在于phoneDirectory::getData 返回data 成员的副本,因此每个迭代器“属于”不同的向量。

您需要它来返回实际成员,而不是它的副本。

  const vector<cityPhone>& getData() const 
  {
      return data;
  }

【讨论】:

    【解决方案2】:

    你有

    void sortByCity(phoneDirectory a){//with these two i try to sort
       vector<cityPhone>::iterator p=a.getData().begin();
       vector<cityPhone>::iterator q=a.getData().end();
       std::sort(p,a.getData().end(),cmpCity);
    }
    

    该功能的问题:

    1. a.getData() 按值返回私有数据的副本。因此,pq 是不同vectors 上的迭代器。比较它们会导致未定义的行为。您不是在比较 pq,而是比较 pgetData().end(),这本质上是一回事。

    2. 由于返回值是a的成员数据的副本,所以这些是临时对象。对象在行执行后被破坏。 pq 相当于悬空指针。

    3. 函数的参数是一个对象。修复上述错误后,您将结束对用于调用函数的参数的副本进行排序。在调用函数中,您仍然不会注意到任何差异。

    函数sortByCode 也有同样的错误。

    如何解决问题

    1. 将函数的参数类型更改为引用。

      void sortByCity(phoneDirectory& a){
      

      通过该更改,您会注意到调用函数中对象的任何更改。

    2. phoneDirectory::getData()的返回值改为引用。

      vector<cityPhone>& getData(){
         return data;
      }
      

    这不仅会修复所有错误,还会对内容进行排序 a 而不是 a 内容的副本。

    【讨论】:

    • 太棒了,你的修复就像一个魅力我知道 p 和 q 与 a.getData() 相同,但我很绝望 :D 我不知道 getData bust 是一个参考,但遗憾的是我没有足够的代表来支持你的评论:)
    猜你喜欢
    • 2012-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多