C++中的Catch Segmentation故障

raj*_*jat 14 c++ crash segmentation-fault

try-catch块是否会捕获分段错误错误?

我正在使用下面给出的函数读取文本文件,但有时文件为空,程序崩溃.我希望程序继续运行,并在此文件为空或正在使用时提供另一个文件.

Path2D read_gesture(const char* filename)
{
    Path2D path;
    //MultiStrokeGesture MultiStrokes;

    vector<string> text_file;

    int no_of_paths=0;
    std::ifstream ifs(filename);

    for (std::string line; std::getline(ifs, line); )
    {
        no_of_paths=no_of_paths+1;
        double a, b;
        stringstream ss(line);
        if (!(ss >> a >> b)) {cout<<"wrong format"<<endl;}
        std::cout << "You said, " << a << ", " << b << ".\n";
        path.push_back(Point2D(a,b));

    }
    cout<<"saving gesture"<<endl;
    return path;


}
Run Code Online (Sandbox Code Playgroud)

我尝试过类似的东西:

Path2D path;
try 
{
    path=read_gesture("test.txt");
}
catch(int e)
{
    path=read_gesture("test2.txt");
}
Run Code Online (Sandbox Code Playgroud)

但程序仍然崩溃.问题可能是什么?

  • 稍微纠正一下,调用的文件与输入的文件catch不一样try,这是一个错字.

小智 35

C++ try-catch块只处理C++异常.像分段错误这样的错误是较低级别的,try-catch会忽略这些事件,并且行为与没有try-catch块的行为相同.


bam*_*s53 12

try/catch仅捕获C++异常.只有当您的程序执行非法操作并调用未定义的行为时,才会发生分段错误.

请记住,未定义的行为可以以不同的方式显示,包括不崩溃.你很幸运让你的程序崩溃,告诉你需要修复的东西,但程序可能不会崩溃; 你不能让你的后备代码取决于崩溃.

适当的做法是不像处理异常那样处理崩溃,而是确保程序不会做任何违法行为,即使输入不是您所期望的.在这种情况下,您需要更改代码,以便知道文件何时为空并需要提供另一个.


通常有一种方法可以处理分段错误,但它并不打算进行您正在寻找的那种恢复.机制是信号.您可以安装一个信号处理程序,该信号处理程序在引发指定信号时执行,例如SIGSEGV用于分段错误.但是,除非您使用std :: raise显式提升它,否则不要求实际发生这样的信号.此外,当信号由实现引发时,您可以在信号处理程序中执行的操作受到严格限制;

如果信号不是作为调用abort或raise函数的结果而发生的,那么如果信号处理程序引用具有静态存储持续时间的任何对象,而不是通过将值赋给声明为volatile sig_atomic_t的对象或信号,则行为是未定义的. handler调用标准库中除了abort函数,_Exit函数或signal函数之外的任何函数,第一个参数等于与导致调用处理程序调用的信号对应的信号编号.此外,如果对signal函数的这种调用导致SIG_ERR返回,则errno的值是不确定的.


Die*_*Epp 6

如果您的程序存在分段错误,并且不是故意执行的操作,那么您将无能为力。您无法捕获它,即使可以捕获,也无法在以后继续执行该程序。

此外,以下代码有一个非常严重的问题:

try {
    path=read_gesture("test.txt");
}
catch(int e) {
    path=read_gesture("test.txt");
}
Run Code Online (Sandbox Code Playgroud)

对于人类来说,“如果一开始没有成功,请重试”是一个很好的座右铭,但是计算机每次都以完全相同的方式进行操作。如果操作失败,除非是暂时性失败(例如网络故障),则重试是徒劳的。

您唯一的选择是编写正确的程序,因为正确的程序不会分段。如果要查找段错误,可以在Valgrind或GDB中运行程序,这两个程序都应提供完整的线索回溯(但您必须动脑筋才能在程序中找到真正的错误)。

另一种选择是使用一种不会出现段错误的语言,例如Java,C#,Python,Ruby,Haskell,JavaScript,Go,Rust或除C或C ++以外的几乎所有如今使用的语言。

脚注:这有点简化,因为实际上有可能编写出遇到分段错误的正确程序。但是,这不是您要做的。