当前位置:C++技术网 > 资讯 > C语言高级应用——解决方案(指针快排)

C语言高级应用——解决方案(指针快排)

更新时间:2015-07-22 10:54:10浏览次数:1+次

    这讲主要是解决“C语言高级应用——指针快排”留下的问题。一步一步的教大家调试程序,有可能有些比较深的知识点大家还很陌生,不要紧,跟着就教程多调试几遍再理解就好了,学东西嘛,都是开头难。

    一般项目中拿到源代码都要先VIEW一下,整体把握代码框架。当然,在这讲里大家都知道是多级指针的快排,以后大家做项目时一定要先VIEW一下,对于整够项目框架做到心中有数。

Step 1:先跑一下程序,看看程序有什么问题。错误提示如下:

      

         int ret = 0;
	 char **myArray3 = NULL;
	 int num3 = 0;
	 //第一种内存模型
	 char *myArray[] = {"bbbbb", "aaa", "ccccccc"};//指针数组
	 char *myp = "1111111ddd";//字符数组

 

以上几句都是定义变量,这个倒好理解,再看看下面的自定义函数SortArrayAndGen3Mem()

Step 3:找到函数体,大体上看看它的功能。其有调用了getArrayMem()sortArray()函数;

Step 4:再看看这两个函数的定义,知道他们的作用;

Step 5:回到main()函数,再往下看,差不多就是释放堆内存,结束程序了。

好了,到这里差不多整个项目代码就VIEW完了,哪些地方容易出问题也大体可以“猜”出来了(程序写多了,就知道常见问题容易出现在哪了)

下面进入Debug

Step 1: SortArrayAndGen3Mem下断点(BreakPoint)1,右击鼠标右键选择“Insert/Remove BreakPoint”或者快捷键F9

 

Step 2F5开始跑程序,遇到断点,程序会自动停住;继续单步执行程序

      

Step 3:一直单步执行,发现执行到freeArray()时出错了,

好了,找到问题所在的位置了,结束本次调试。

重新开始Debug,现在在freeArray()函数出下断点,并跟进去,看看到底哪边出问题了

发现下面这段代码执行第二次时就出问题了

好了,这次更近一步找出问题了,我们再去看看free(temArray[i]),根据源程序发现temArray[i]即为myArray3[]数组元素,好了,那就直接看myArray3数组就好了。发现整够程序只有SortArrayAndGen3Mem()内部会改变myArray3也即sortArray()函数会改变myArray3数组,到sortArray()函数里去看看,主要部分就是这个if语句:

       if(strcmp(p[i], p[j]) > 0)
			{				
				strcpy(tmp, p[i]);
				strcpy(p[i], p[j]);
				strcpy(p[j], tmp);
			}

注意看,这个strcpy是将p[i]与p[j]所指起始地址的字符串互换。这个函数可是个“问题函数”,微软的大部分缓冲区溢出漏洞都是拜其所赐。主要原因是它不能指定目的缓冲区的长度,当源缓冲区长度超过目的缓冲区的长度,会破坏栈帧或者堆结构2,这样一来程序就崩溃了。

下面来看看这里的strcpy到底有什么问题,回到源程序,看看数组   

char *myArray[] = {"bbbbb", "aaa", "ccccccc"};//指针数组 

看到了吧,不等长,意味着将"ccccccc"拷贝到"aaa"肯定会发生溢出,原因就是上面说的,既然问题找到了,那么如何解决呢?

思路:既然是字符窜不等长,复制会有溢出问题,那么什么才是等长的呢?指针啊,指针在32位机子上不都是四个字节吗?哦,问题解决了,聪明的你一定已经知道答案了,互动下吧。

 

注:1断点就是一种系统支持的异常,当设置断点后,程序运行到断点处时,调试器产生异常,这个异常被调试器捕捉,调试器暂停程序运行。

    2栈帧,对结构是一种数据结构,后面会有讲,当然也可以先上网查查

今天的调试过程略微简单,主要是讲解这个问题的解决过程,至于调试步骤,后边会有详细教程