在c ++中执行后出现“段错误”错误

时间:2014-01-17 08:57:38

标签: c++ g++ segmentation-fault dev-c++

我对此代码有疑问。该程序旨在使用c ++中的深度优先搜索。我用Dev-Cpp,TurboC ++和visual studio。编译了它,并编写了exe文件。但它会在执行期间产生段错误。哪里有问题,我该怎么办?

#include <stdio.h>
#include <string.h>
#include <iostream.h>
#include <vector.h>
#include <deque.h>

using namespace std;

//Structure for Adding Edge to Graph

struct Neighbor         
{                   
    string Name;            
    int Distance;           
    int ShortestDistance;   
};                  

//Class Data Structure for City type Node:

class   City                                
{                                   
public:                             
    string              Name;                           

    City( );                            
    City(string);                           

    vector<Neighbor>        Neighbors;          
    vector<Neighbor>::iterator  NeighborNumber;

    void    AddNeighbor (string, int);          


};  

//Parameterless Class constructor                               

City::City( )
{
    Name="";
    NeighborNumber=Neighbors.begin( );
}

//Class Constructor with Name supplied:

City::City(string CityName)
{
    Name=CityName;
    NeighborNumber=Neighbors.begin( );
}

//Function or Method to Add Connected Node to City data structure

void    City::AddNeighbor(string NeighborName, int NeighborDistance)
{
    Neighbor TempNeighbor;
    TempNeighbor.Name=NeighborName;
    TempNeighbor.Distance=NeighborDistance;
    Neighbors.push_back(TempNeighbor);
    NeighborNumber=Neighbors.begin( );
}

//Data Structure for Entire Map

vector<City>    Cities;

void    MakeMap()
{
    City TempCity;

//Enter data for Arad

    TempCity.Name="Arad";
    TempCity.Neighbors.clear();

    TempCity.AddNeighbor("Zerind",75);
    TempCity.AddNeighbor("Sibiu", 140);
    TempCity.AddNeighbor("Timisoara",118);
    Cities.push_back(TempCity);

//Enter data for Bucharest

    TempCity.Name="Bucharest";
    TempCity.Neighbors.clear();
    TempCity.AddNeighbor("Giurgiu",90);
    TempCity.AddNeighbor("Urziceni",85);
    TempCity.AddNeighbor("Fagaras",211);
    TempCity.AddNeighbor("Pitesti",101);
    Cities.push_back(TempCity);
}
//Function to Display contents of Cities data structure to screen:

void    PrintCities()
{
    City        TempCity;
    Neighbor    TempNeighbor;

    vector<City>::iterator  CityNumber;

//Loop Through Entire Cities vector

    for(CityNumber=Cities.begin();CityNumber<Cities.end();CityNumber++)
    {
        TempCity=*CityNumber;
        cout<<"Current City: "<<TempCity.Name<<endl;
        cout<<"Neighbors: ";

//Loop Through Each Neighbor printing name and distance

        for(TempCity.NeighborNumber=TempCity.Neighbors.begin();
            TempCity.NeighborNumber<TempCity.Neighbors.end();
                TempCity.NeighborNumber++)
        {
            TempNeighbor=*TempCity.NeighborNumber;
            cout<<"  "<<TempNeighbor.Name;
            cout<<","<<TempNeighbor.Distance;
        }
        cout<<endl<<endl;
    }
}
//Function to return Success or Failure on finding the Child Node given the
//Parent is a structure of type Neighbor. The ChildCity is returned by reference.

bool    GetChildCity(Neighbor Parent, City* ChildCity)
{
    City            TempCity;
    vector<City>::iterator  CityNumber;

    for(CityNumber=Cities.begin();CityNumber<Cities.end();CityNumber++)
    {
        TempCity=*CityNumber;

        if(TempCity.Name==Parent.Name)
        {
            *ChildCity=TempCity;
            return true;
        }
    }
    return false;
}

class   PathRecord
{
public:
    string  AccumulatedPath;
    string  LastEntry;
    int AccumulatedDistance;

    PathRecord(string);
    void    AddPath(PathRecord, City, Neighbor);
};

PathRecord::PathRecord(string Start)
{
    AccumulatedPath=Start;
    LastEntry=Start;
    AccumulatedDistance=0;
}

void    PathRecord::AddPath(PathRecord ParentRecord, City ChildCity, Neighbor CurrentNeighbor)
{
    this->AccumulatedPath=ParentRecord.AccumulatedPath+" - "+ChildCity.Name;
    this->LastEntry=ChildCity.Name;
    this->AccumulatedDistance=ParentRecord.AccumulatedDistance+CurrentNeighbor.Distance;
}

vector<PathRecord>  PathsTraveled;

//Perform Depth First Search giving Start Location and Ending Location

bool    DepthFirstSearch(string StartName, string EndName)
{   
    City        CurrentCity;
    City        StartCity;
    City        ChildCity;
    City        ExploredCity;
    City        FrontierCity;

    Neighbor    CurrentNeighbor;

    bool    StartCityFound=false;
    bool    GoalFound=false;
    bool    AlreadyExplored;
    bool    AlreadyInFrontier;
    bool    NewChildFound;
    bool    PathFound;

    vector<City>::iterator  CityNumber;

    deque<City>         Frontier;
    deque<City>         Explored;

    deque<City>::iterator   FrontierCityNumber;
    deque<City>::iterator   ExploredCityNumber;

    PathRecord              NewRecord(StartName);
    PathRecord              TemporaryRecord("");

    vector<PathRecord>::iterator    PathNumber;

    if(StartName==EndName) return true;

    if(StartName=="" || EndName == "") return false;

//*************************************************************************
//          Search For Start
//*************************************************************************

    for(CityNumber=Cities.begin();CityNumber<Cities.end();CityNumber++)
    {
        CurrentCity=*CityNumber;
        if(CurrentCity.Name==StartName)
        {
            StartCity=CurrentCity;
            StartCityFound=true;
        }
    }

    if(StartCityFound==false) return false;

    PathsTraveled.push_back(NewRecord);
    Frontier.push_back(StartCity);

//*************************************************************************
//          Search For Goal
//*************************************************************************

    cout<<"\nRecording Exploratory Process:\n"<<"Start Location: "<<
        StartName<<"\t Ending Location: "<<EndName<<endl;

//Get Next Location in the Frontier

    while(!Frontier.empty() && GoalFound==false)
    {
        CurrentCity=Frontier.back();
        cout<<"\nCurrent City: "<<CurrentCity.Name<<endl;
        NewChildFound=false;

//Look through the Neighbors until an explored City is found.

        while(CurrentCity.NeighborNumber<CurrentCity.Neighbors.end() && NewChildFound==false)
        {
            CurrentNeighbor=*CurrentCity.NeighborNumber;
            cout<<"Current Neighbor: "<<CurrentNeighbor.Name<<endl;
            if(GetChildCity(CurrentNeighbor, &ChildCity)==false) 
            {
                cout<<"Didn't find a child\n";
                return false;
            }
            if(ChildCity.Name==EndName) 
            {
                cout<<"Goal Found\n";
                GoalFound=true;
            }

//Check for Child Already Explored

            AlreadyExplored=false;
            ExploredCityNumber=Explored.begin();

            while(AlreadyExplored==false && ExploredCityNumber<Explored.end())
            {
                ExploredCity=*ExploredCityNumber;

                if(ExploredCity.Name==ChildCity.Name) AlreadyExplored=true;
                ExploredCityNumber++;
            }


//Check for Child Already in Frontier

            if(AlreadyExplored==false)
            {
                AlreadyInFrontier=false;
                FrontierCityNumber=Frontier.begin();

                while(AlreadyInFrontier==false && FrontierCityNumber<Frontier.end())
                {
                    FrontierCity=*FrontierCityNumber;

                    if(FrontierCity.Name==ChildCity.Name) AlreadyInFrontier=true;
                    FrontierCityNumber++;
                }

            }

//Put the parent in the Frontier queue and Expand the Child Node
//Record the process in the Paths Traveled vector.

            if(AlreadyExplored==false && AlreadyInFrontier==false)
            {
                Frontier.push_back(ChildCity);
                NewChildFound=true;
                PathNumber=PathsTraveled.begin( );
                PathFound=false;
                while(PathFound==false && PathNumber<PathsTraveled.end( ))
                {
                    TemporaryRecord=*PathNumber;
                    if(TemporaryRecord.LastEntry==CurrentCity.Name)
                    {
                        NewRecord.AddPath(TemporaryRecord, 
                            ChildCity, CurrentNeighbor);
                        PathsTraveled.push_back(NewRecord);
                        PathFound=true;
                    }
                    PathNumber++;
                }
            }

            CurrentCity.NeighborNumber++;
        }

//Display the Explored Queue on each pass

        if(NewChildFound==false) 
        {
            Explored.push_back(CurrentCity);
            Frontier.pop_back();
        }

        cout<<"Explored: ";

        for(ExploredCityNumber=Explored.begin();
            ExploredCityNumber<Explored.end();ExploredCityNumber++)
        {
            ExploredCity=*ExploredCityNumber;
            cout<<ExploredCity.Name<<" \t";
        }
        cout<<endl;

//Display the Frontier Queue on each pass

        cout<<"Frontier: ";
        for(FrontierCityNumber=Frontier.begin(); 
            FrontierCityNumber<Frontier.end();FrontierCityNumber++)
        {
            FrontierCity=*FrontierCityNumber;
            cout<<FrontierCity.Name<<" \t";
        }
        cout<<endl;
    }

    return GoalFound;
}

//Goal Path will print the path used to locate the Goal
//Supply the name of the goal after a search has been successful

void    PrintGoalPath(string GoalName)
{
    vector<PathRecord>::iterator    PathNumber;
    PathRecord          TemporaryRecord("");

    cout<<"\nGoal Path:  "<<endl;

    for(PathNumber=PathsTraveled.begin();PathNumber<PathsTraveled.end();PathNumber++)
    {
        TemporaryRecord=*PathNumber;
        if(TemporaryRecord.LastEntry==GoalName)
            cout<<TemporaryRecord.AccumulatedPath
                <<"  "<<TemporaryRecord.AccumulatedDistance<<endl;
    }
    cout<<endl;
}

//Program Starts here:

int main()
{
    bool    GoalFound;

    MakeMap();
    string  StartLocation="Arad";
    string GoalState="Bucharest";
    GoalFound=DepthFirstSearch(StartLocation, GoalState);
    if(GoalFound) PrintGoalPath(GoalState);
        else    cout<<"Couldn't Do It - "<<GoalState<<" is nowhere to be found!!\n";
    return 0;
}

#include <stdio.h> #include <string.h> #include <iostream.h> #include <vector.h> #include <deque.h> using namespace std; //Structure for Adding Edge to Graph struct Neighbor { string Name; int Distance; int ShortestDistance; }; //Class Data Structure for City type Node: class City { public: string Name; City( ); City(string); vector<Neighbor> Neighbors; vector<Neighbor>::iterator NeighborNumber; void AddNeighbor (string, int); }; //Parameterless Class constructor City::City( ) { Name=""; NeighborNumber=Neighbors.begin( ); } //Class Constructor with Name supplied: City::City(string CityName) { Name=CityName; NeighborNumber=Neighbors.begin( ); } //Function or Method to Add Connected Node to City data structure void City::AddNeighbor(string NeighborName, int NeighborDistance) { Neighbor TempNeighbor; TempNeighbor.Name=NeighborName; TempNeighbor.Distance=NeighborDistance; Neighbors.push_back(TempNeighbor); NeighborNumber=Neighbors.begin( ); } //Data Structure for Entire Map vector<City> Cities; void MakeMap() { City TempCity; //Enter data for Arad TempCity.Name="Arad"; TempCity.Neighbors.clear(); TempCity.AddNeighbor("Zerind",75); TempCity.AddNeighbor("Sibiu", 140); TempCity.AddNeighbor("Timisoara",118); Cities.push_back(TempCity); //Enter data for Bucharest TempCity.Name="Bucharest"; TempCity.Neighbors.clear(); TempCity.AddNeighbor("Giurgiu",90); TempCity.AddNeighbor("Urziceni",85); TempCity.AddNeighbor("Fagaras",211); TempCity.AddNeighbor("Pitesti",101); Cities.push_back(TempCity); } //Function to Display contents of Cities data structure to screen: void PrintCities() { City TempCity; Neighbor TempNeighbor; vector<City>::iterator CityNumber; //Loop Through Entire Cities vector for(CityNumber=Cities.begin();CityNumber<Cities.end();CityNumber++) { TempCity=*CityNumber; cout<<"Current City: "<<TempCity.Name<<endl; cout<<"Neighbors: "; //Loop Through Each Neighbor printing name and distance for(TempCity.NeighborNumber=TempCity.Neighbors.begin(); TempCity.NeighborNumber<TempCity.Neighbors.end(); TempCity.NeighborNumber++) { TempNeighbor=*TempCity.NeighborNumber; cout<<" "<<TempNeighbor.Name; cout<<","<<TempNeighbor.Distance; } cout<<endl<<endl; } } //Function to return Success or Failure on finding the Child Node given the //Parent is a structure of type Neighbor. The ChildCity is returned by reference. bool GetChildCity(Neighbor Parent, City* ChildCity) { City TempCity; vector<City>::iterator CityNumber; for(CityNumber=Cities.begin();CityNumber<Cities.end();CityNumber++) { TempCity=*CityNumber; if(TempCity.Name==Parent.Name) { *ChildCity=TempCity; return true; } } return false; } class PathRecord { public: string AccumulatedPath; string LastEntry; int AccumulatedDistance; PathRecord(string); void AddPath(PathRecord, City, Neighbor); }; PathRecord::PathRecord(string Start) { AccumulatedPath=Start; LastEntry=Start; AccumulatedDistance=0; } void PathRecord::AddPath(PathRecord ParentRecord, City ChildCity, Neighbor CurrentNeighbor) { this->AccumulatedPath=ParentRecord.AccumulatedPath+" - "+ChildCity.Name; this->LastEntry=ChildCity.Name; this->AccumulatedDistance=ParentRecord.AccumulatedDistance+CurrentNeighbor.Distance; } vector<PathRecord> PathsTraveled; //Perform Depth First Search giving Start Location and Ending Location bool DepthFirstSearch(string StartName, string EndName) { City CurrentCity; City StartCity; City ChildCity; City ExploredCity; City FrontierCity; Neighbor CurrentNeighbor; bool StartCityFound=false; bool GoalFound=false; bool AlreadyExplored; bool AlreadyInFrontier; bool NewChildFound; bool PathFound; vector<City>::iterator CityNumber; deque<City> Frontier; deque<City> Explored; deque<City>::iterator FrontierCityNumber; deque<City>::iterator ExploredCityNumber; PathRecord NewRecord(StartName); PathRecord TemporaryRecord(""); vector<PathRecord>::iterator PathNumber; if(StartName==EndName) return true; if(StartName=="" || EndName == "") return false; //************************************************************************* // Search For Start //************************************************************************* for(CityNumber=Cities.begin();CityNumber<Cities.end();CityNumber++) { CurrentCity=*CityNumber; if(CurrentCity.Name==StartName) { StartCity=CurrentCity; StartCityFound=true; } } if(StartCityFound==false) return false; PathsTraveled.push_back(NewRecord); Frontier.push_back(StartCity); //************************************************************************* // Search For Goal //************************************************************************* cout<<"\nRecording Exploratory Process:\n"<<"Start Location: "<< StartName<<"\t Ending Location: "<<EndName<<endl; //Get Next Location in the Frontier while(!Frontier.empty() && GoalFound==false) { CurrentCity=Frontier.back(); cout<<"\nCurrent City: "<<CurrentCity.Name<<endl; NewChildFound=false; //Look through the Neighbors until an explored City is found. while(CurrentCity.NeighborNumber<CurrentCity.Neighbors.end() && NewChildFound==false) { CurrentNeighbor=*CurrentCity.NeighborNumber; cout<<"Current Neighbor: "<<CurrentNeighbor.Name<<endl; if(GetChildCity(CurrentNeighbor, &ChildCity)==false) { cout<<"Didn't find a child\n"; return false; } if(ChildCity.Name==EndName) { cout<<"Goal Found\n"; GoalFound=true; } //Check for Child Already Explored AlreadyExplored=false; ExploredCityNumber=Explored.begin(); while(AlreadyExplored==false && ExploredCityNumber<Explored.end()) { ExploredCity=*ExploredCityNumber; if(ExploredCity.Name==ChildCity.Name) AlreadyExplored=true; ExploredCityNumber++; } //Check for Child Already in Frontier if(AlreadyExplored==false) { AlreadyInFrontier=false; FrontierCityNumber=Frontier.begin(); while(AlreadyInFrontier==false && FrontierCityNumber<Frontier.end()) { FrontierCity=*FrontierCityNumber; if(FrontierCity.Name==ChildCity.Name) AlreadyInFrontier=true; FrontierCityNumber++; } } //Put the parent in the Frontier queue and Expand the Child Node //Record the process in the Paths Traveled vector. if(AlreadyExplored==false && AlreadyInFrontier==false) { Frontier.push_back(ChildCity); NewChildFound=true; PathNumber=PathsTraveled.begin( ); PathFound=false; while(PathFound==false && PathNumber<PathsTraveled.end( )) { TemporaryRecord=*PathNumber; if(TemporaryRecord.LastEntry==CurrentCity.Name) { NewRecord.AddPath(TemporaryRecord, ChildCity, CurrentNeighbor); PathsTraveled.push_back(NewRecord); PathFound=true; } PathNumber++; } } CurrentCity.NeighborNumber++; } //Display the Explored Queue on each pass if(NewChildFound==false) { Explored.push_back(CurrentCity); Frontier.pop_back(); } cout<<"Explored: "; for(ExploredCityNumber=Explored.begin(); ExploredCityNumber<Explored.end();ExploredCityNumber++) { ExploredCity=*ExploredCityNumber; cout<<ExploredCity.Name<<" \t"; } cout<<endl; //Display the Frontier Queue on each pass cout<<"Frontier: "; for(FrontierCityNumber=Frontier.begin(); FrontierCityNumber<Frontier.end();FrontierCityNumber++) { FrontierCity=*FrontierCityNumber; cout<<FrontierCity.Name<<" \t"; } cout<<endl; } return GoalFound; } //Goal Path will print the path used to locate the Goal //Supply the name of the goal after a search has been successful void PrintGoalPath(string GoalName) { vector<PathRecord>::iterator PathNumber; PathRecord TemporaryRecord(""); cout<<"\nGoal Path: "<<endl; for(PathNumber=PathsTraveled.begin();PathNumber<PathsTraveled.end();PathNumber++) { TemporaryRecord=*PathNumber; if(TemporaryRecord.LastEntry==GoalName) cout<<TemporaryRecord.AccumulatedPath <<" "<<TemporaryRecord.AccumulatedDistance<<endl; } cout<<endl; } //Program Starts here: int main() { bool GoalFound; MakeMap(); string StartLocation="Arad"; string GoalState="Bucharest"; GoalFound=DepthFirstSearch(StartLocation, GoalState); if(GoalFound) PrintGoalPath(GoalState); else cout<<"Couldn't Do It - "<<GoalState<<" is nowhere to be found!!\n"; return 0; }

1 个答案:

答案 0 :(得分:2)

段错误意味着您已尝试访问超出段边界的内存,可能是代码或数据段。

错误是:

  

矢量迭代器不兼容

为什么?
因为您已经将数组从A复制到B,但是您想使用A.begin()迭代器与B的迭代器进行比较,并且这不会在Visual Studio中传递编译器的兼容性检查,

    void _Compat(const _Myiter& _Right) const
    {   // test for compatible iterator pair
    if (this->_Getcont() == 0
        || this->_Getcont() != _Right._Getcont())
        {   // report error
        _DEBUG_ERROR("vector iterators incompatible");
        _SCL_SECURE_INVALID_ARGUMENT;
        }
    }

所以我的建议是,不要试图保存指向向量的迭代器开始,你可以在需要时使用临时迭代器

进一步的建议,系统地学习C ++,除非你有足够的信心,否则不要按照你的想法编写代码。

来吧,努力工作,你可以做到!