一次地址越界的调试
具体现象描述:
1. 看程序本身,好象没有什么问题,先不说算法正不正确,但确确实实没有出现修改sum1,sum2变量的情况
2. 运行的情况来看,发现输出的sum1和sum2并不是输入的值,显然,是程序在运行过程中,发生了改变
3. 从VC编译器换到GCC下,也一样
4. 插入pritntf旗进行输出查点看,看不到问题,但可以发现,循环完成时,数据被修改了
某个同学,在做作业时,写出了如下的代码
#include <stdio.h>
int main(void)
{
int sum1, sum2, i, arr[7], ben = 0, ss = 0, j, flat, aa[100], kk, shu;
printf("please input m, n(5<=m<=n<=100000): ");
scanf("%d,%d", &sum1, &sum2);
for (i = sum1; i <= sum2; i++)
{
printf("i = %d\n",i);
shu = i;
while (shu != 0)
{
arr[ben] = shu % 10;
shu = shu / 10;
ben++;
}
if (arr[0] == arr[ben - 1])
{
for (j = 2; j < i; j++)
{
flat = 0;
if (i % j == 0)
{
break;
}
else
{
flat = 1;
}
}
}
if (flat == 1)
{
aa[ss] = i;
ss++;
}
}
printf("Result(%d-%d):\n", sum1, sum2);
for (kk = 0; kk < ss; kk++)
{
printf("%d ", aa[kk]);
}
return 0;
}
然后,观察输出时,与自己的预期差了很远,在没有修改sum1和sum2的情况下,看到sum1和sum2被修改了。
这显然无法解释,直觉上,应该是地址覆盖了。启用调试。
1 先插旗
- 发现程序会退出在11左右,即i增长到以11时,for就退出了,问题可能出在这里
- 使用printf插旗,但并不能发现问题
- 既然数据量不大,直接跟踪打表,进行调试
2 打断点,进行调试发现
- ben计数器没有还原,在上一次的基础上进行的计数,无法让程序达到预期
- 跟踪到ben增长为7,8时,就发现问题所在,然后观察相应的地址,就发现了问题
- 所以,写程序时,数组在使用时,一定要注意检查地址越界的情况
3 以后,出现莫名其妙的问题时,要注意检查内存地址越界的情况
- 学习编程,一定要会调试
- 调试要讲技巧和方法
- 调试要有足够的耐心,要积极思考,相信真觉
- 要学会定位到关键节点,进行内存上的值的观察,也要进行地址的观察
- 要充分理解C的内存机制,内存分配机制
|