确保程序在C ++ / fortran

时间:2016-01-29 22:34:16

标签: c++ gcc segmentation-fault fortran

简而言之:

是否有一些通用且可靠的方法来确保程序总是在发生某些不好的事情(比如写入不属于我的内存)的地方崩溃?

EG。一些gcc flags喜欢-Og -g -fbounds-check ...?

(分别为g++ / gfortran

更长的解释:

我想避免的真实例子:

通常,当我遇到运行时错误时,我会将一堆编号的调试消息写入printf("DEBUG %i \n", 15 );之类的代码中,以查看它在哪里崩溃(在Java中运行良好)。

但是最近我错误地用一段代码写了外部分配的数组,其功能类似于:

int ny = 6;
int nz = 60;
zs = new double[ny];
for(int i=0; i<nz; i++){
    zs[i] = i/(double)nz;
}
但是,不是立即触发分段错误,而是由memory corruption在完全不相关的位置显示此错误(不同对象的内部方法称为20行之后,即鼠标处理rutine SDL_pollEvent())。 / p>

我完全无法理解鼠标处理如何与我正在处理的代码部分(该数组的初始化)相关联。所以我花了很长时间才找到它。

我还尝试在gdb甚至Code::Blocks中使用Valgrind,调试器来查找错误(即使我对其用法不是很熟悉)...但是所有它们表明SDL_pollEvent()

中发生了内存损坏

前段时间我遇到了与fortran类似的问题(不确定是ifort还是gfortran

3 个答案:

答案 0 :(得分:2)

在Fortran中,至少使用数组边界检查和指针检查(-fcheck=all,参见https://gcc.gnu.org/onlinedocs/gfortran/Code-Gen-Options.html)。它不是万能的,但可以经常拯救你。特别是,它能够诊断您的示例中出现的那种错误。它还可以诊断,当您仍在正确的缓冲区内时,但您在其中一个维度中关闭

   allocate(a(10,10))
   ...
   x = a(11,1)

C(动态)数组通常不能轻易检查,因为它们只是一个地址。您可以对C和Fortran使用清理,但它们更昂贵。它由fsanitize=...启用,请参阅编译器手册了解所有可能性,=all中没有-fcheck

答案 1 :(得分:1)

不,您无法确保程序可靠且一致地崩溃。 C ++并不要求代码明确检查导致未定义行为的操作,因此结果完全不可预测。当您导致内存损坏时,它可以位于进程内存中的任何位置。是否以及何时导致崩溃取决于您损坏的内存中发生的情况,以及它在程序中稍后使用的方式。

在C ++中,最好的办法是避免使用低级C风格的数组和指针,并利用std::vectorstd::string,{{1}等高级数据结构等等。

答案 2 :(得分:0)

一般来说,没有。 C ++程序只有在调用未定义的行为时才会崩溃,这意味着任何事情都可能发生 - 包括忽略您可能碰巧添加的任何诊断。

(抱歉,Fortran无法帮助。)