以前一直用VS 2012来调试C/C++代码,F5、F10、F11用起来甚是顺手,前面也写过一篇关于VS最好用的快捷键:Visual Studio最好用的快捷键(你最喜欢哪个), 所以对于调试C/C++代码我一直钟情于VS。可最近下载了一个linux环境下用C++编写的开源库,准备进行一番研究,由于我对gdb调试只处在初步 阶段,还没有对整个项目用gdb调试过,而且gdb调试看起来也不方便,还是VS看的直观。为了省懒和省时间就将代码弄到VS中进行编译调试,结果发现编 译不成功,因为里面出现了很多类似int block[2*n];这样的变长数组。大家知道传统C语言和C++是不支持变长数组功能的,不过在C99标准中新增的一项功能就是允许在C语言和C++ 中使用变长数组,节省了很多资源。可恨的是,微软的编译器跟不上时代的步伐,C++11都出来这么久了,微软到现在连C99还不完全支持(不知道最新版的 VS 2013支不支持),不知道是故意而为之还是其它什么原因。既然VS不支持变长数组,我这程序就调试不了,我也不可能一个个的把它改成定长的。后来想到用 Eclipse CDT进行调试,就下载了个完整的Eclipse CDT(没在已有的Eclipse上安装CDT插件而是下载了个完全用于C/C++开发的Eclipse,因为配置插件出现了很多问题,至今还待解决)。 Eclipse中的C/C++库支持使用的是最新版的Cygwin,最新的g++肯定是支持变长数组的,这时也发现我下载的库的原作者也是在 Eclipse CDT下开发该项目的,因为工程目录下有.cproject和.project这两个文件,因此认为在Eclipse CDT下编译调试该工程是最佳选择。经过尝试,编译是通过了,可是运行时老是出现这样一个错误:No source available for "ntdll!ZwWriteFile() at 0x77a4133a"

aaarticlea/png;base64,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" alt="" />

然后各种google、百度都搜不到相关的信息或只有少数几个没什么价值的信息。看来只能断点调试了,发现了问题所在位置:

    if(i!=0){
re[i]='\0';
if (re[0]!= '#'){
j++;
if (j>=from && (to==-1 || j<=to)){
if (DEBUG) fprintf(stdout,"\n%d) processing regex:: <%s> ...\n",j,re);
parse_re(nfa,re);
}
}
free(re);
}
if (DEBUG) fprintf(stdout, "\nAll RegEx processed\n"); if (re!=NULL) free(re); //handle -m modifier
if (m_modifier && (!anchored->get_epsilon()->empty() || !anchored->get_transitions()->empty())){
non_anchored->add_transition('\n',anchored);
non_anchored->add_transition('\r',anchored);
} // delete non_anchored, if necessary
if(non_anchored->get_epsilon()->empty() && non_anchored->get_transitions()->empty()){
nfa->get_epsilon()->remove(non_anchored);
delete non_anchored;
}else{
non_anchored->add_any(non_anchored);
}

发现每次判断该条件语句if (m_modifier...)过后才报上面那个错误,所以坚信是这条语句有问题,经过一番检查觉得这语句没啥问题,无奈之下干脆将两个判断条件全部注释掉了,结果还是出现问题,问题转到注释语句的下面,实在不清楚是啥原因,就仔细看了下“No source available for "ntdll!ZwWriteFile() at 0x77a4133a"这
条错误语句,发现是和ntdll库有关,于是就搜ntdll库错误相关的资料,最终发现可能是跟堆相关,可还是没能解决问题。最终我还是转到VS下面调
试,当然前提是去掉了变长数组(还好发现变长数组只出现在两个文件的两个函数中,直接注释掉了),编译成功后运行出现错误:

点Continue接着出现错误:

看了下错误信息真的是堆问题,调试下发现是这句if (re!=NULL)
free(re);执行不了,再次调试发现前面re这个对象已经通过free(re)释放了,这里按理说re应该为NULL了也就是不会再次
free(re)了啊,可是实际运行的确re不为NULL因此再次free了re,相当于一块本来已经释放了的内存空间再次被释放,肯定会出现堆错误了。
将该条件语句注释掉后,运行成功,然后在Eclipse下注释掉该句也是运行成功。现在问题就来了:

1. 为什么free(re)过后re不为NULL呢?

我一直认为将一个对象free过后该对象就为NULL了,这样就可以通过判断该对象是 否为NULL来知道该对象是否为正确的释放了,如果没有释放(上面的代码中也就是if(i!=0)没执行)那么在此进行释放以避免内存泄露。这个工程库中也是这样做的,可是通过调试却发现不是这样的情况,现在我能想到的唯一解释就是:free(re)过后re所指内存空间的确被释放了,但re本身的值不会改变,也就是形参的值没有改变,所以re还是原来的值当然就不是NULL了,这样后面的再次free也就会被执行,但re所指的内存已经被释放所以再次 free也就失败了。后来经过网友@hazir的解释,知道了原来是“野指针”的问题,即:若指针p被free或者delete之后,p并没有置为NULL,让人误以为p是个合法的指针,别看free和 delete的名字(尤其是delete),它们只是把指针所指的内存给释放掉,但并没有把指针本身干掉,此时指针成为了“野指针”,指向的就是“垃圾”内存。知道了原因过后,那么以后怎么判断re所指的内存是否被释放了呢?当然上面的代码很好解决,直接在if(i!=0)后面加 else{ free(re); }也就解决了,可是其它情况呢?为了防止“野指针”的产生,编程最佳实践都建议:释放后的指针应立即将指针置为NULL,例:

free( p );
if ( p != NULL )
p = NULL;

但是并不是每个野指针再次free过后都会报错的,只要下次有另一个指针分配内存且以这个地址为起始地址开始分配,那么free就不会报错,具体看下面的测试片段:

#include <stdio.h>
#include <stdlib.h> void main() {
int *pint1, *pint2;
pint1 = (int *) malloc (12);
printf("pint alloc at : %p\n", pint1); //free pint1, and pint1 do not change to NULL
free(pint1);
printf("after free pint, and pint is :%p\n", pint1); //pint2 alloc the same start address with pint1
pint2 = (int *) malloc (12);
printf("pint2 alloc at : %p\n", pint2); //free pint1 again, not pint2, and not occur error!!!
free(pint1);
}

运行结果如下:

aaarticlea/png;base64,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" alt="" />

足以说明野指针的使用是不确定的,所以为了不出现bug还是遵守我上面所说的最佳实践做法吧。

2. Eclipse中为什么调试不出来这个错误呢?

Eclipse的调试功能也十分强大,可是这里的调试却不友善,一个是错误信息看不 懂,一个是出错位置调试不出来,虽然出错位置就在调试出来的位置的正上面,但调试的时候if (re!=NULL) free(re);这句的确是执行成功了,所以也就不会认为是这句的问题,难道程序真正的出错位置是在Eclipse下调试出来的出错位置的正上面吗?额,应该不会吧。

下面不得不简单比较下VS和Eclipse调试功能的差异:

1. 首先如果你习惯了用VS的调试,那么转到Eclipse下可能会有些不太习惯,尤其是大家熟知的VS下的F5、F10、F11到了Eclipse下却变成了F8、F6、F5,其它的也不同,这样的转变有时候真不习惯。

2. 我觉得Eclipse下调试有一点的确比VS好,就是对函数的智能提示,Eclipse下当你讲鼠标放到一个自定义函数上面,会自动显示该函数的实现,而VS下只能显示该函数的声明,要知道定义还得按F12跳过去。

Eclipse下:

VS下:

其它的我就不多作比较了,比如快捷键方面,因为对VS快捷键较熟,对Eclipse快捷键还不是很了解(虽然自己最熟的语言是Java,但调试Java的次数较少),所以两者快捷键方便的差异性我也就不太清楚了,如果清楚的麻烦告诉我。

好了,以自己亲自调试的一
个小错误引出了这么一个问题:Eclipse与VS,你更喜欢哪个呢?当然有人会说,开发C/C++与C#就用VS,开发Java就用Eclipse,可
是Eclipse可不仅仅是Java的编辑器,Eclipse是全能型的,可以编译常见的所有语言如C/C++、C#、Python、Ruby等等,如果
你钟爱Eclipse,完全可以用它来开发你想要开发的任何程序。

VS和Eclipse的调试功能哪个更强大?的更多相关文章

  1. Eclipse的调试功能的10个小窍门[转]

    原文链接:http://www.importnew.com/6164.html 你可能已经看过一些类似“关于调试的N件事”的文章了.但我想我每天大概在调试上会花掉1个小时,这是非常多的时间了.所以非常 ...

  2. Eclipse的调试功能的10个小窍门

    你可能已经看过一些类似“关于调试的N件事”的文章了.但我想我每天大概在调试上会花掉1个小时,这是非常多的时间了.所以非常值得我们来了解一些用得到的功能,可以帮我们节约很多时间.所以在这个主题上值得我再 ...

  3. Eclipse的调试功能(转)(让Eclipse也能有VS的即时窗口那样的即时代码调试功能)

    前言:可以很明确的说明,eclipse也有像vs那样的即时窗口来运行即时代码的功能. 调试的界面如下: 如果要像vs那样的即时调试功能,需要做一些设置,就是Expressions功能. 开通步骤:Wi ...

  4. [转载]eclipse的远程调试功能配置

    原文地址:eclipse的远程调试功能配置作者:我的 用途:web应用部署并运行于外部(区别于eclipse环境中启动的)应用服务器中,当出现问题时,可以使用eclipse工程的源代码进行跟踪调试. ...

  5. Android动态方式破解apk前奏篇(Eclipse动态调试smail源码)

    一.前言 今天我们开始apk破解的另外一种方式:动态代码调试破解,之前其实已经在一篇文章中说到如何破解apk了: Android中使用静态方式破解Apk  主要采用的是静态方式,步骤也很简单,首先使用 ...

  6. Eclipse断点调试方法

    1. 条件断点 断点大家都比较熟悉,在Eclipse Java 编辑区的行头双击就会得到一个断点,代码会运行到此处时停止. 条件断点,顾名思义就是一个有一定条件的断点,只有满足了用户设置的条件,代码才 ...

  7. Eclipse中调试Android技巧

    Android eclipse中程序调试 一:断点调试 用eclipse开发android程序的时,跟VS一样是可以断点单步调试的. 步骤如下. 1 设置断点:在编码窗体的左边框上用鼠标双击,或者右键 ...

  8. Android Studio调试功能使用总结【转】

    Android Studio调试功能使用总结[转]   这段时间一直在使用Intellij IDEA, 今天把调试区工具的使用方法记录于此. 先编译好要调试的程序. 1.设置断点 选定要设置断点的代码 ...

  9. eclipse debug (调试) 学习心得

    eclipse debug (调试) 学习心得   进入debug模式:   1.设置断点   2.启动servers端的debug模式   3.运行程序,在后台遇到断点时,进入debug调试状态   ...

随机推荐

  1. Job Interview: Why Only 3 Questions Really Matter

    Even for the most fearless amongst us, job interviews can be nerve wracking. In order to give us the ...

  2. How to resolve "your security settings have blocked an untrusted application from running" in Mac

    If you encounter the error "your security settings have blocked an untrusted application from r ...

  3. Linux常用备份恢复工具

    在 Linux 中可以通过各种各样的方法来执行备份.所涉及的技术从非常简单的脚本驱动的方法,到精心设计的商业化软件.备份可以保存到远程网络设备.磁带驱动器和其他可移动媒体上.备份可以是基于文件的或基于 ...

  4. springMvc里的mvc:resources与静态资源的访问

    在进行Spring MVC的配置时,通常我们会配置一个dispatcher servlet用于处理对应的URL.配置如下:   <servlet>   <servlet-name&g ...

  5. IP地址和域

    1. 0. 0. 0到 126.255.255.255为A类 主要分配给具有大量主机而局域网络数量较少的大型网络 128.0.0.0到191.255.255.255为B类 一般用于国际性大公司和政府机 ...

  6. PSP个人项目耗时对比记录表:四则运算

    Personal Software Process Stages Time(%) 计划 5    •估计这个任务需要多长时间 5 开发 60    •需求分析  5    •生成设计文档  5     ...

  7. [实战演练]蜻蜓FM2014年校招笔试题目 - 规则二叉树

    题目:某规则二叉树的定义是:对于树中任意两个叶结点A.B,他们与根结点的距离分别是d1和d2,|d1-d2|<=1.请写出函数 bool isRuledTree(Node *root)的代码实现 ...

  8. Nginx负载均衡初识

    1.背景 nginx是一款自由的.开源的.高性能的HTTP服务器和反向代理服务器:同时也是一个IMAP.POP3.SMTP代理服务器:nginx可以作为一个HTTP服务器进行网站的发布处理,另外ngi ...

  9. Android-----application的学习

    一.Application的对象回调函数 1.onCreate : Application对象被创建时候会调用 2.onConfigurationChanged : 屏幕方向变化.系统语言的更改等 3 ...

  10. JavaScript基础(2)-DOM

    一.伪数组arguments arguments代表的是实参,有个讲究的地方是:arguments只在函数中使用. 1.返回函数实参的个数:arguments.length,例如: fn(2,4); ...