Question

i have a problem with this codes. this program designed to use depth-first search in c++. i compiled it with Dev-Cpp , TurboC++ and visual studio .it compiled and the exe file have been made. but it make segment fault during execute. where is problem and what should i do ?

#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;
}

Was it helpful?

Solution

Segment Fault means you have tried to access memory beyond the boundary of segment, maybe code or data segment.

The error is :

vector iterators incompatible

Why?
Because you have copied an Array from A to B, but you want to use A.begin() iterator to compare with B's iterator, and this will not pass compiler's compatibility check, in 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;
        }
    }

So my advice is ,do not try to save the iterator that points to the vector begin, you can use a temporary iterator when need

And further advice, learn C++ systematically, do not write codes as you think unless you have enough confidence.

Come on, work hard, you can make it!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top