我在c ++中为Octave编写了一个名为“hello”的动态链接函数。
#include <octave/oct.h>
DEFUN_DLD (hello, args, ,"Print 42") {
try{
octave_value retval ;
throw ;
return retval = 42.0 ;
}
catch(...){
std::cerr << "An error has occurred!" << std::endl;
}
}
我使用“throw”抛出异常来模拟“hello”中可能出现的任何错误。我在Octave终端使用“system”“mkoctfile”编译“hello”。
octave:2> system('mkoctfile /home/b/Desktop/hello.cc')
ans = 0
“system”返回“0”表示未发现错误。我在Octave终端中运行“hello”作为动态链接函数,这是我收到的终端消息:
octave:3> hello
terminate called without an active exception
panic: Aborted -- stopping myself...
attempting to save variables to 'octave-workspace'...
save to 'octave-workspace' complete
Aborted
是否有可能捕获错误并阻止Octave在每次执行“hello”测试运行时终止?我非常感谢一个小的示例代码,它会抛出一个豁免,并允许Octave继续运行而不会终止,如果我可以显示错误导致错误的位置或原因的消息,那就更好了。感谢。
==== 2014年2月9日新增==================================== =======================
感谢Carandraug向我解释终止异常和非终止异常之间的区别。下面的代码是我遇到的非故意终止异常的示例。使用Carandraug提供的代码,我添加了第8行和第9行,它们模拟了一个无意的终止异常,以模拟我编写带有致命错误的代码。
#include <octave/oct.h>
DEFUN_DLD (hello, args, ,"Print 42") {
octave_value retval;
try {
Matrix matrix_temp ; // line 8
matrix_temp(-1,-1) = 1; // line 9
}
catch(...) {
error ("An error has occurred!");
return retval;
}
return retval = 42;
}
使用Carandraug关于为Octave编译动态链接函数的建议我遇到了以下Octave终止:
octave:3> mkoctfile /home/gin/Desktop/hello.cc
octave:4> hello
*** glibc detected *** octave: double free or corruption (out): 0x0000000002225740 ***
======= Backtrace: =========
...
octave[0x400561]
======= Memory map: ========
...
pack.so.3gf.0panic: Aborted -- stopping myself...
attempting to save variables to `octave-core'...
save to `octave-core' complete
Aborted (core dumped)
我根据Carandraug提供的信息编辑了“终止例外”一词的问题标题。如果我必须将修改后的问题移到自己的帖子中,请告诉我。
当我遇到这个错误时,我做了一个粗略的假设,即我会无意中在代码中创建其他导致Octave终止的致命错误。我预见到这可能是一个令人烦恼的调试过程,特别是如果终止后的Octave不能提供有关导致错误的更多信息。但是,我认为它们可能只是少数可能写入的错误,这些错误太明显而不能导致终止异常,或者这只是编写没有“安全性”的c ++代码的本质。网框工作“我习惯了。
答案 0 :(得分:3)
这是Octave自己的代码中的example,可以捕获来自其他库的错误。问题是空的throw语句实际上意味着现在终止或传播前一个throw(see related SO question)。在您的示例中,立即终止执行是正确的操作。
以下是对您的示例的简单修改(当一切顺利到最后时,我冒昧地改变返回,并在捕获中返回“坏”):
#include <octave/oct.h>
DEFUN_DLD (hello, args, ,"Print 42") {
octave_value retval;
try {
throw 1;
}
catch(...) {
error ("An error has occurred!");
return retval;
}
return retval = 42;
}
请注意,要使用Octave打印错误消息,您应该使用Octave's error。注意,在调用error()之后,不要为你要返回的任何值而烦恼。
最后,请注意您不需要使用system('mkoctfile path_to_source')
。 Octave已经具有可以从Octave提示符调用的函数mkoctfile
。以下就足够了
octave-cli-3.8.0:1> mkoctfile hello.cc
octave-cli-3.8.0:1> hello
error: An error has occurred!
编辑:回答第二个问题
您看到的错误不是可以捕获的错误。 Octave并没有像第一个例子中那样在终止指令时抛出无法捕获的错误。这是一个段错误,因为您正在尝试访问不存在的元素。你正在尝试相当于
std::vector<int> v (5);
v[7] = 8;
v[-1] = 2;
如果要防止此错误,请在编制索引之前检查矩阵的大小。您不再使用Octave脚本语言,您应该知道自己在做什么。此段错误是您的代码中的错误,您需要对其进行说明,例如:
Matrix m = ...; // the matrix whose elements you want to access
octave_idx_type i = ...; // the element index you want to access
if (i < m.numel ())
// do something with m(i)
else
error ("Dude! This is out-of-bounds");
所有这一切都说,有一个Octave构建选项将检查你是否试图从边界中访问一个元素,但我认为默认是关闭的(可能是因为每次访问元素时都会检查这个元素)性能大打折扣。)