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
,这是一个错字.bam*_*s53 12
try/catch仅捕获C++异常.只有当您的程序执行非法操作并调用未定义的行为时,才会发生分段错误.
请记住,未定义的行为可以以不同的方式显示,包括不崩溃.你很幸运让你的程序崩溃,告诉你需要修复的东西,但程序可能不会崩溃; 你不能让你的后备代码取决于崩溃.
适当的做法是不像处理异常那样处理崩溃,而是确保程序不会做任何违法行为,即使输入不是您所期望的.在这种情况下,您需要更改代码,以便知道文件何时为空并需要提供另一个.
通常有一种方法可以处理分段错误,但它并不打算进行您正在寻找的那种恢复.机制是信号.您可以安装一个信号处理程序,该信号处理程序在引发指定信号时执行,例如SIGSEGV用于分段错误.但是,除非您使用std :: raise显式提升它,否则不要求实际发生这样的信号.此外,当信号由实现引发时,您可以在信号处理程序中执行的操作受到严格限制;
如果信号不是作为调用abort或raise函数的结果而发生的,那么如果信号处理程序引用具有静态存储持续时间的任何对象,而不是通过将值赋给声明为volatile sig_atomic_t的对象或信号,则行为是未定义的. handler调用标准库中除了abort函数,_Exit函数或signal函数之外的任何函数,第一个参数等于与导致调用处理程序调用的信号对应的信号编号.此外,如果对signal函数的这种调用导致SIG_ERR返回,则errno的值是不确定的.
如果您的程序存在分段错误,并且不是故意执行的操作,那么您将无能为力。您无法捕获它,即使可以捕获,也无法在以后继续执行该程序。
此外,以下代码有一个非常严重的问题:
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 ++以外的几乎所有如今使用的语言。
脚注:这有点简化,因为实际上有可能编写出遇到分段错误的正确程序。但是,这不是您要做的。