关于c++中的Debug以及runtime_error之segment_fault
差不多每次编一些竞赛类的程序都会至少给我报一次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. |
另外,这里有个基本上对照的中文解释,来自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的异常判断我们可以看出是否出现错误
在判断确实出现错误以后我们可以借助调试器观察错误位置
经过观察,我们确定错误位于蓝色行的"%d",a处
改正就可以了
段错误是算法竞赛中很容易出现的一种错误,我们应该学会使用各种方法尽快加以解决。
关于c++中的Debug以及runtime_error之segment_fault的更多相关文章
- 怎样在myEclipse中使用debug调试程序?
怎样在myEclipse中使用debug调试程序? 最基本的操作是: 1.首先在一个java文件中设断点,然后debug as-->open debug Dialog,然后在对话框中选类 ...
- 在Salesforce中通过 Debug Log 方式 跟踪逻辑流程
在Salesforce中通过 Debug Log方式 跟踪逻辑流程 具体位置如下所示: Setup ---> Logs ---> Debug Logs ---> Monitored ...
- 在Intellij IDEA中使用Debug
Debug用来追踪代码的运行流程,通常在程序运行过程中出现异常,启用Debug模式可以分析定位异常发生的位置,以及在运行过程中参数的变化.通常我们也可以启用Debug模式来跟踪代码的运行流程去学习三方 ...
- 【技巧】Java工程中的Debug信息分级输出接口
也许本文的标题你们没咋看懂.但是,本文将带大家领略输出调试的威力. 灵感来源 说到灵感,其实是源于笔者在修复服务器的ssh故障时的一个发现. 这个学期初,同袍(容我来一波广告产品页面,同袍官网)原服务 ...
- 【技巧】Java工程中的Debug信息分级输出接口及部署模式
也许本文的标题你们没咋看懂.但是,本文将带大家领略输出调试的威力. 灵感来源 说到灵感,其实是源于笔者在修复服务器的ssh故障时的一个发现. 这个学期初,同袍(容我来一波广告产品页面,同袍官网)原服务 ...
- 在Visual Studio中使用Debug Visualizers在C++中实现对原始类的自定义调试信息显示
在Visual Studio中使用Debug Visualizers在C++中实现对原始类的自定义调试信息显示 当我们在VS的C++中使用vector.list.map等这些STL容器,在开启调试的时 ...
- VS中的Debug 和 Release 编译方式的本质区别
VS中的Debug 和 Release 编译方式的本质区别 Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序.Release 称为发布版本,它往往是进行了各种优化,使 ...
- 二十、在Intellij IDEA中使用Debug
Debug用来追踪代码的运行流程,通常在程序运行过程中出现异常,启用Debug模式可以分析定位异常发生的位置,以及在运行过程中参数的变化.通常我们也可以启用Debug模式来跟踪代码的运行流程去学习三方 ...
- Intellij IDEA中使用Debug
Intellij IDEA中使用Debug Debug用来追踪代码的运行流程,通常在程序运行过程中出现异常,启用Debug模式可以分析定位异常发生的位置,以及在运行过程中参数的变化.通常我们也可以启用 ...
随机推荐
- CCPlace,CCFlip*,CCToggleVisibility,CCMoveTo*,CCJumpTo*,CCScale*,CCRotate*,CCSkew*,fade,CCCardinalSp*
1 CCAction动作 CCAction作为一个基类.事实上质是一个接口(即抽象类),由它派生的实现类(如运动和转动等)才是我们实际使用的动作.CCAction 的绝大多数实现类都派生自CCF ...
- EF 导航属性的使用
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...
- jquery腾讯微博
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 投资人的能量往往大多远远不仅于此,他能站在不同的角度和高度看问题(要早点拿投资,要舍得让出股份)——最好不要让 Leader 一边做技术、一边做管理,人的能力是有限的,精力也是有限的
摘要:在创业三年时间里作为联合创始人,虽然拿着大家均等的股份,我始终是没有什么话语权的,但是,这也给了我从旁观者的角度看清整个局面的机会.创业公司的成败绝大程度取决于技术大牛和公司 Leader, ...
- java设计模式(2)
工厂模式定义 在面向对象程序设计中,工厂通常是用来创建其他对象的对象,工产模式根据不同的参数来实现不同的分配方案和创建对象. 在工产模式中,我们创建对象时不会对客户端暴露创建逻辑,而且是通过使用一个共 ...
- WPF里DataGrid分页控件
1.主要代码: using System; using System.Collections.ObjectModel; using System.Windows; using System.Windo ...
- SQL Server 2016新特性:DROP IF EXISTS
原文:SQL Server 2016新特性:DROP IF EXISTS 在我们写T-SQL要删除某个对象(表.存储过程等)时,一般会习惯先用IF语句判断该对象是否存在,然后DROP,比如: 旧 ...
- scons编译mongodb(vs2008版本)遇到的问题总结
OS:win7 64 boost:1.49 mongodb:2.4.6(推荐64位版本,当然如果你系统是32位的,只能使用32的版本了) IDE:vs2008(2010的同学请跳过吧,因为官网提供的就 ...
- 理解typedef(转)
// 从别人那转的,调整下格式便于阅读. 首先请看看下面这两句: typedef ]; typedef void (*p)(void); 如果你能一眼就看出它们的意思,那请不要再往下看了.如果你不太理 ...
- MFC OnPaint()函数中最先调用CDialog::OnPaint()和最后调用CDialog::OnPaint()的巨大区别
OnPaint()函数中最先调用CDialog::OnPaint()和最后调用CDialog::OnPaint()的巨大区别,如果没有注意这个问题就会出现无厘头式的绘图问题-- 效果就是出不来!在经过 ...