在c ++中执行后出现“段错误”错误[关闭]

Posted

技术标签:

【中文标题】在c ++中执行后出现“段错误”错误[关闭]【英文标题】:"segment fault" error after execute in c++ [closed] 【发布时间】:2014-01-17 08:57:38 【问题描述】:

我对此代码有疑问。该程序旨在使用 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;

【问题讨论】:

lolwut - 您是否尝试过调试它以查看崩溃的位置? 是的,我已调试,但我找不到崩溃线 :( 怎么样?将断点设置为“bool GoalFound”,然后继续。 尝试检查您的迭代器是否与向量的末端不同 ('!='),而不是在 'for' 语句中更小 (' 崩溃会发生在 GoalFound=DepthFirstSearch(StartLocation, GoalState); 【参考方案1】:

Segment Fault 表示您试图访问超出段边界的内存,可能是代码或数据段。

错误是:

向量迭代器不兼容

为什么? 因为你已经从 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++,除非你有足够的信心,否则不要像你想的那样写代码。

加油,努力,一定能成功!

【讨论】:

每当我看到有人写“代码”时,我都会提醒自己,我的防核避难所的钥匙还在他们应该在的地方。

以上是关于在c ++中执行后出现“段错误”错误[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

为啥在使用 Python/C API 时会出现此段错误?

exec 出现段错误后更新主窗口标题

准系统 SWIG python C 接口在 OSX+clang 上出现段错误,而不是在 Linux+gcc 中

为啥我的代码在 Windows 7 上不会出现段错误?

C语言 文件方面 段错误 核心已转储 以及字符串查找删除的问题

CUDA 矩阵加法段错误