差不多每次编一些竞赛类的程序都会至少给我报一次runtime_error(运行时错误)。这或许也是广大OIer心中永远的痛。~_~

本文主要讨论如何对runtime_error以及其中的segment_fault部分进行调试。本文以dev-c++5.11作为环境,由于以竞赛为主,本文不涉及指针、c++中的类等部分。

下面所有经验,均为本人在编程过程中所实际涉及并进行应用。


一、关于runtime_error(运行时错误)

  运行时错误大概分为以下几类:

  1、访问到不应访问的地址(如数组越界)

  2、内存溢出(如数组过大)

  3、算术上溢或下溢(如除以0)

  4、段错误(各种其它错误)

  除最后一种情况的一部分外,剩余错误发生时通常会在执行.exe文件时显示“已停止运行”。

  (一)地址越界及溢出

    通常情况下(不考虑指针地址非法)数组开过大会导致编译错误(Complie Error)。但是访问下标负数或数组过小会导致访问到数组以外的范围。

    除将数组范围增大之外,通常情况下可以开一个新数组,当数组内存溢出时多余内容会流入新数组以避免错误发生(不推荐这种做法,无法确定内容剩余部分)。

  (二)算术上溢及下溢

    我们可以在每个可能出现错误的位置尝试c++中的try-throw-catch子句。

    比如遇到除以0:

    

#include <iostream>
using std::cout;
using std::cin;
using std::cerr;
int fun(int &a, int &b)
{
if(b == )
{
throw "hello there have zero sorry\n"; //引发异常
}
return a / b;
}
int main()
{
int a;
int b;
while(true)
{
cin >> a;
cin >> b;
try //try里面是可能引发异常代码块
{
cout << " a / b = "<< fun(a,b) << "\n";
}
   catch(const char *str) //接收异常,处理异常 括号内是类型
   {
   cout << str;
 cerr <<"除数为0\n"; //cerr不会到输出缓冲中 这样在紧急情况下也可以使用
  }
      catch(...)//可以捕捉任何类型的异常
     {
       cerr <<"未知错误\n";
     }
}
system("pause");
return ;//异常结束 }

    try:try块标识符其中特定的异常可能被激活的代码块,他后面跟一个或者多个catch块.

    catch:类似于函数定义,但并不是函数定义,关键字catch表明这是给一个处理程序, 里面的const  cahr *str 会接受throw传过来错误信息.

    throw:抛出异常信息,类似于执行返回语句,因为它将终止函数的执行,但是它不是将控制权交给调用程序,而是导致程序沿着函数调用序列后退,知道找到包含try块的函数.

  (三)对segment_fault的处理

   下面是来自Answers.com的定义:

A segmentation fault (often shortened to segfault) is a particular error condition that can occur during the operation of computer software. In short, a segmentation fault occurs when a program attempts to access a memory location that it is not allowed to access, or attempts to access a memory location in a way that is not allowed (e.g., attempts to write to a read-only location, or to overwrite part of the operating system). Systems based on processors like the Motorola 68000 tend to refer to these events as Address or Bus errors.
Segmentation is one approach to memory management and protection in the operating system. It has been superseded by paging for most purposes, but much of the terminology of segmentation is still used, "segmentation fault" being an example. Some operating systems still have segmentation at some logical level although paging is used as the main memory management policy.
On Unix-like operating systems, a process that accesses invalid memory receives the SIGSEGV signal. On Microsoft Windows, a process that accesses invalid memory receives the STATUS_ACCESS_VIOLATION exception.

   另外,这里有个基本上对照的中文解释,来自http://www.linux999.org/html_sql/3/132559.htm

   所谓的段错误 就是指访问的内存超出了系统所给这个程序的内存空间,通常这个值是由gdtr来保存的,他是一个48位的寄存器,其中的32位是保存由它指向的gdt表, 后13位保存相应于gdt的下标,最后3位包括了程序是否在内存中以及程序的在cpu中的运行级别,指向的gdt是由以64位为一个单位的表,在这张表中 就保存着程序运行的代码段以及数据段的起始地址以及与此相应的段限和页面交换还有程序运行级别还有内存粒度等等的信息。一旦一个程序发生了越界访 问,cpu就会产生相应的异常保护,于是segmentation fault就出现了

   实际上同前面一样,段错误也是访问到了非法的内存,它会抛出SIGSEGV信号,可以通过signal或者dev-c++自带调试器捕捉。

     比如说:

   

    其中scanf调用了a而不是&a

    这时我们可以借助c++中的assert函数捕捉异常

    assert函数的用法自己看

    首先我们初步判断这里出现了段错误,借助assert的异常判断我们可以看出是否出现错误

    

    在判断确实出现错误以后我们可以借助调试器观察错误位置

    

    经过观察,我们确定错误位于蓝色行的"%d",a处

    改正就可以了


段错误是算法竞赛中很容易出现的一种错误,我们应该学会使用各种方法尽快加以解决。

关于c++中的Debug以及runtime_error之segment_fault的更多相关文章

  1. 怎样在myEclipse中使用debug调试程序?

    怎样在myEclipse中使用debug调试程序? 最基本的操作是:     1.首先在一个java文件中设断点,然后debug as-->open debug Dialog,然后在对话框中选类 ...

  2. 在Salesforce中通过 Debug Log 方式 跟踪逻辑流程

    在Salesforce中通过 Debug Log方式 跟踪逻辑流程 具体位置如下所示: Setup ---> Logs ---> Debug Logs ---> Monitored ...

  3. 在Intellij IDEA中使用Debug

    Debug用来追踪代码的运行流程,通常在程序运行过程中出现异常,启用Debug模式可以分析定位异常发生的位置,以及在运行过程中参数的变化.通常我们也可以启用Debug模式来跟踪代码的运行流程去学习三方 ...

  4. 【技巧】Java工程中的Debug信息分级输出接口

    也许本文的标题你们没咋看懂.但是,本文将带大家领略输出调试的威力. 灵感来源 说到灵感,其实是源于笔者在修复服务器的ssh故障时的一个发现. 这个学期初,同袍(容我来一波广告产品页面,同袍官网)原服务 ...

  5. 【技巧】Java工程中的Debug信息分级输出接口及部署模式

    也许本文的标题你们没咋看懂.但是,本文将带大家领略输出调试的威力. 灵感来源 说到灵感,其实是源于笔者在修复服务器的ssh故障时的一个发现. 这个学期初,同袍(容我来一波广告产品页面,同袍官网)原服务 ...

  6. 在Visual Studio中使用Debug Visualizers在C++中实现对原始类的自定义调试信息显示

    在Visual Studio中使用Debug Visualizers在C++中实现对原始类的自定义调试信息显示 当我们在VS的C++中使用vector.list.map等这些STL容器,在开启调试的时 ...

  7. VS中的Debug 和 Release 编译方式的本质区别

    VS中的Debug 和 Release 编译方式的本质区别 Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序.Release 称为发布版本,它往往是进行了各种优化,使 ...

  8. 二十、在Intellij IDEA中使用Debug

    Debug用来追踪代码的运行流程,通常在程序运行过程中出现异常,启用Debug模式可以分析定位异常发生的位置,以及在运行过程中参数的变化.通常我们也可以启用Debug模式来跟踪代码的运行流程去学习三方 ...

  9. Intellij IDEA中使用Debug

    Intellij IDEA中使用Debug Debug用来追踪代码的运行流程,通常在程序运行过程中出现异常,启用Debug模式可以分析定位异常发生的位置,以及在运行过程中参数的变化.通常我们也可以启用 ...

随机推荐

  1. nyoj 92 图片实用面积【bfs】

    图像实用区域 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描写叙述 "ACKing"同学曾经做一个图像处理的项目时.遇到了一个问题,他须要摘取出图片中某 ...

  2. Http请求格式(在Linux下使用telnet亲测,通过这篇我才明白)

    命令行窗口中用telnet测试HTTP协议请求消息格式响应消息格式1. 命令行窗口中用telnet测试HTTP协议 HTTP消息是由普通ASCII文本组成.消息包括消息头和数据体部分.消息头以行为单位 ...

  3. Emgu-WPF 激光雷达研究-移动物体跟踪2

    原文:Emgu-WPF 激光雷达研究-移动物体跟踪2 初步实现了去燥跟踪,并用圆点标注障碍物 https://blog.csdn.net/u013224722/article/details/8078 ...

  4. jquery 隐私迭代

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  5. 用蓝牙连接debian和诺基亚手机

    本方法已经用debian 4.0.诺基亚9300和一个hl-united牌子的USB蓝牙适配器测试过了,效果很好.             1.安装必要的软件包:   #apt-get install ...

  6. 图像滤镜艺术---PS图像转手绘特效实现方案

    原文:图像滤镜艺术---PS图像转手绘特效实现方案 手绘效果实现方案 本文介绍一种PS手绘效果的实现方案,PS步骤来自网络,本文介绍代码实现过程. 整体看来,虽然效果还是有很大差异,但是已经有了这种特 ...

  7. C#连接oracle 数据库查询时输入中文查询不出来,用plsql就可以

    查询语句为:select * from Per where khmc like '%李%',其实是字符集的问题. 解决方案:在连接字符串加一个“Unicode=True;”

  8. C#如何将十六进制数字符串转byte[]?

    代码: /// <summary> /// 16进制原码字符串转字节数组 /// </summary> /// <param name="hexString&q ...

  9. Oracle 存储过程创建及调用

    --------创建存储过程------- create or replace procedure TestSPas begin update table_name set CREATE_TIMEST ...

  10. php 的mvc开发

    至于什么MVC结构,其实就是三个Model,Contraller,View单词的简称,,Model,主要任务就是把数据库或者其他文件系统的数据按 照我们需要的方式读取出来.View,主要负责页面的,把 ...