由一个bug想到的

    在暑假用VC++做的一个工程里面,有获取系统时间并保存为字符串的一段代码,如下:

	获得当前年月日,给全局变量strCurTime赋值///
	CTime currenttime = CTime::GetCurrentTime();//获得当前时间
	if( currenttime.GetMonth() < 10 && currenttime.GetDay() < 10 )//月份,日期都是个位数,补0
		strCurTime.Format("%d0%d0%d",currenttime.GetYear(),currenttime.GetMonth(),currenttime.GetDay());
	else if( currenttime.GetMonth() < 10 )//月份是个位数,日期不是个位数,月份前补0
		strCurTime.Format("%d0%d%d",currenttime.GetYear(),currenttime.GetMonth(),currenttime.GetDay());
	else if( currenttime.GetDay() < 10 )//月份不是个位数,日期是个位数,日期前补0
		strCurTime.Format("%d%d0%d",currenttime.GetYear(),currenttime.GetMonth(),currenttime.GetDay());

 
 
这段代码有问题,恰巧在单位数月份或单位数日期时运行不会出错,在月份和日期都是两位数时运行就会出问题。
做这个工程的时候是7、8月份,当时没有问题,现在10月份拿出来一运行就崩溃。

下面详细展示了我如何由报错找到问题所在:
崩溃后提示是STREX.CPP文件的第332行出现问题,windows搜索找出STREX.CPP文件,貌似里面是字符串操作的扩展功能。
找到第332行,如下:ASSERT(nFirst + nCount <= GetData()->nDataLength);
找到此句所在的函数:CString::Mid(int nFirst, int nCount),是从字符串中截取一段的函数,想到可能是调用Mid时下标越界。
在程序原文件中查找Mid函数,看看都在哪里用到。其中一句如下:
m_EDIT_CAM = strCurTime.Left(4)+"年"+strCurTime.Mid(4,2)+"月"+strCurTime.Right(2)+"日," + m_EDIT_CAM;
//strCurTime是全局变量,表示当前年月日,格式:YYYYMMDD
想到可能是strCurTime这个字符串有问题,这个字符串是在程序初始化函数中赋值的,遂找到程序初始化函数。
就找到了文章开头的那段代码,在此段代码后加一条输出语句做测试,输出strCurTime的值,发现竟然是空的。
仔细看这段代码,终于恍然大悟,发现一个很弱智但又很有意思的考虑不周全导致的bug。
月份和日期都是两位数时,不属于三个判断语句中的任何一个,所以不会给strCurTime赋值。
由此导致strCurTime是空字符串,再导致Mid函数越界,触发Assert,进而导致程序崩溃。

此过程学到了什么?
不是以后写代码时应该更加仔细,而是由错误一环一环向前推理,找出错误根源的能力。
因为人总会有考虑不全的时候,你再仔细还是会出错。linux的设计者Linus Torvalds在写linux内核时也留下了bug。
我觉得这类似“授之以鱼不如授之以渔”。
分析问题的能力是更重要的。

             —— 2012年10月14日   masikkk

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值