确保程序在运行时出错时在 C++/fortran 中的适当位置崩溃

Ensure that program crash on runtime error at proper place in C++/fortran

本文关键字:位置 崩溃 fortran 运行时 程序 出错 C++ 确保      更新时间:2023-10-16

简而言之:

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

例如,一些像-Og -g -fbounds-check这样的gcc flags...?

( 或 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行后调用的不同对象的内部方法,即在鼠标处理芦丁SDL_pollEvent()(。

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

我还尝试使用gdb,调试器Code::Blocks甚至Valgrind来查找错误(即使我不太熟悉它的用法(...但他们都表明内存损坏发生在SDL_pollEvent()

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

在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=... 启用的,请参阅编译器手册以了解所有可能性,没有像 -fcheck 那样=all

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

在C++中,最好的办法是避免使用低级的C式数组和指针,而使用高级数据结构,如std::vectorstd::stringstd::shared_ptr等。

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

(对不起,不能帮助Fortran。