1.核心已转储
进入solve_函数前即发生了错误 |
求解非常简单的cnf,trail中没有队列文字却传播结束并出现“核心已转储错误” |
分析:不同求解器给出两种sat结论 v 1 2 3 4 5 6 7 0 或者 v 1 2 3 -4 -5 -6 -7 0 说明可满足样例的指派不止一个。仔细分析该cnf中有最后两句是重言式。
该文件内容 ----------------------------------- p cnf 7 7 ------------------------------------ |
换了一个求解器,居然没有上述报错!——新增加的代码造成的异常? |
2.图形指针悬空时使用——改正办法在构造函数中或使用该指针前构建对象交给该指针指向。
输出错误文件名称:SnapCmtYesMapleLCMDistChronoBT-DL-v2.2UIP03.Err |
内容: -------- |
bd.h, line 490内容 TRec* operator->() const {Assert(Addr!=NULL); return Addr;} |
3. 运行错误时,发生 (SIGSEGV)错误,没有任何提示。如何查找错误并修改?
举例:在参加2024年SAT竞赛时,将在cadical1.5.3修改代码迁移到cadical1.9.4上时,编译正常,但是运行时发生了错误:截图如下:
|
|
由于没有任何提示,所以查找错误十分艰难。在将修改部分注意排查后确定了大致位置。但找不出究竟什么错误。 此时,发现:(1)assert没有任何作用。(2)printf输出不了。 |
|
原因: (1)正常bugger模式编译通过后,为了增加运行速度将编译器模式由模式调整为release模式,依靠编译器的优化功能增加编译出来的程序运行效率。此时assert会失效! (2)SIGSEGV错误属于段错误,遇到此类错误内存没有来的及刷新输出即报错,因而在屏幕上看不到想要的printf输出结果。 |
|
解决办法: 找到configure文件打开并查找"-O3". 得到: -f*|-ggdb3|-O|-O1|-O2|-O3) options="$options $1";; 说明gcc编译器有四种编译模式。 x*g++*|x*clang++*) CXXFLAGS="$CXXFLAGS -O3";; 说明当前选用的时-O3模式,是最优的优化模式。 将3改为1,即可保证编译模式为普通的调试模式。此时编译后运行发生错误时,屏幕会有相关提示。 我们找到示例错误为访问了空的reason。增加判断(reason!=nullptr)即将问题解决了。
|
|
此外,通过在configure文件中下面语句可以了解一些编译模式和选项: [ $check = no ] && CXXFLAGS="$CXXFLAGS -DNDEBUG" [ $logging = yes ] && CXXFLAGS="$CXXFLAGS -DLOGGING" [ $quiet = yes ] && CXXFLAGS="$CXXFLAGS -DQUIET" [ $profile = yes ] && CXXFLAGS="$CXXFLAGS -pg" [ $coverage = yes ] && CXXFLAGS="$CXXFLAGS -ftest-coverage -fprofile-arcs"
|
|
4. 内存泄漏
内存泄漏有很多实例。 这里介绍本人遇到的因为疏忽,循环代码拷贝粘贴改动后造成的计算平台根目录下大量临时文件,占用大量内存资源,程序运行也发生严重错误。希望引以为戒。 for (i =0; (tail.size()-1); i++) { //循环判断始终为真,发生严重的错误。 ... }
|
|
如果一个向量为空,写下面的代码,在检查严格的cadical194中运行过程中也会报错。 1 // vIsLeaf本身为空向量 2 3 for (int i = (vIsLeafs.size() - 1); i >= 0; i--) 4 { 5 int dec_lit = vIsLeafs[i]; 6 。。。。。。 7 }
|
|