vc调试经验总结.doc_第1页
vc调试经验总结.doc_第2页
vc调试经验总结.doc_第3页
vc调试经验总结.doc_第4页
vc调试经验总结.doc_第5页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

vc调试经验总结 调试经验总结-VC下的错误对话框很早前就想写点总结将编程中遇到的各种错误刨根挖底地罗列出来。 但是因为这些错误(VC中开调试器遇到的各种错误对话框)都是随机性的,真正想总结的时候又不想不起来有哪些错误。 恰好最近运气比较背,各种错误都被我遇遍了,于是恰好有机会做个总结。 这里所说的VC下的错误对话框时指在VC中开调试器运行程序时,IDE弹出的对话框。 1.不是错误的错误断言.将断言视为错误其实有点可笑,但是因为有些同学甚至不知道这个,所以我稍微提一下。 断言对话框大致上类似于断言对话框是由assert引起的,在对话框上通常会给出表达式,例如assert (0);弹出对话框时就会将0这个表达式显示出来(Expression:0)。 关于assert的具体信息建议自己google。 这里稍微提一下一个技巧有时候为了让assert提供更多的信息,我们可以这样写一个assert:assert(expression&Function:invalid argument!);因为字符串被用在布尔表达式中时,始终为true,不会妨碍对expression的判断,当断言发生时(expression为false)时,断言对话框上就会显示这个字符串,从而方便我们调试。 要解决这个问题,首先要确定断言发生的位置,如果是你自己设置的断言被引发,就很好解决,如果是系统内部的函数产生的,那么一般是因为你传入的函数参数无效引起。 2.内存相关最简单的非法访问C、C+程序中经常误用无效的指针,从而大致各种各样的非法内存访问(写/读)。 最简单的情况类似于这样的情况由类似以下代码引起char*p=0;*p=a;当你看到类似于“写入位置XXXX时发生访问冲突“时,那么你大致可以断定,你的程序在某个地方访问到非法内存。 开调试器对调用堆栈进行跟踪即可找出错误。 3.内存相关不小心的栈上数组越界当你写下类似以下的代码时char str3;strcpy(str,abc);就将看到如下的对话框对话框大致的意思就是说str周围的栈被破坏了,因为str本身就被放在栈上,所以strcpy(str,abc)多写入的0就写到非法的栈区域。 看到这样的对话框可以根据调用堆栈定位到错误发生的函数,然后检查此函数内部定义的数组访问,即可解决问题。 4.内存相关不小心的堆上数组越界并不是每次数组越界都会得到上面所描述的错误,当数组是在堆上分配时,情况就变得隐秘得多char*str=new char2;strcpy(str,ab);/执行到这里时并不见得会崩溃deletestr;/但是到这里时就肯定会崩溃以上代码导致的错误对话框还要诡异些似乎不同的DAMAGE对应的错误号(这里是47)都不一样,因为这里的错误发生在delete,而delete跟new很可能在不同的地方,所以这个错误调试起来不是那么容易,很多时候只能靠经验。 当看到类似的对话框时,根据调用堆栈跟到delete时,你就可以大致怀疑堆上数组越界。 5.调用相关函数调用约定带来的错误这是所有我这里描述的错误中最诡异的一种,先看下对话框大致的样子对话框大致的意思就是说(没开调试器时对话框样式可能不一样),通过函数指针调用某个函数时,函数指针的类型(函数原型)可能与函数指针指向的函数的类型不一样。 这里的类型不一致主要是调用约定(call conversation)不一样。 如果函数类型(参数个数,返回值)不一样,一般不会出错。 调用约定是指调用一个函数时,函数参数的压入顺序、谁来清理栈的内容等。 例如默认的C、C+调用约定_cdecl,对于函数的参数是从右往左压入。 而_stdcall(WIN API的调用约定)则是从左向右压。 我这里所说的函数类型不一样,就是指一个函数是使用_cdecl,还是_stdcall。 例如以下代码#includevoid_stdcall show(const char*str)void_stdcall show2()int main()typedef void(*Func)(const char*);void*p=show;Func my_func=(Func)p;my_func(kevin);return0;因为Func默认地被处理为_cdecl,而show是_stdcall的,所以当通过函数指针my_func时,就导致了以上对话框的出现。 但是当p指向show2时,又不会出错,这是因为show2没有参数,不同的调用约定不影响这个规则。 6.异常相关默认终止程序当我们使用C+库时,因为库本身可能会抛出C+异常,如果你不捕获这个异常,那么C+默认就会调用abort(或者exit)函数终止程序。 例如void test()throw std:exception(some exceptions);当你调用test函数时,如果不catch这个异常,开调试器就会得到类似的错误对话框而如果不开调试器,则会得到当你看到类似于“This applicationhas requestedthe Runtimeto terminateit”之类的字眼时,那就表明程序调用了abort(或exit)函数,导致程序异常终止。 其实这个错误只要开调试器,一般可以准确定位错误的发生点。 7.VC运行时检查-未初始化变量VC的调试器会对代码进行运行时检查,这可能会导致VC弹出对你看上去正确的代码。 这也许不是一个错误。 例如int test_var;if(test_var=-1)test_var=0;test_var没有初始化就进行if判断,当运行以上代码开调试器时,就会得到如下对话框8.破坏的堆VC对于在堆上分配的内存

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论