现在的位置: 首页 > 综合 > 正文

注意内存越界

2017年11月08日 ⁄ 综合 ⁄ 共 953字 ⁄ 字号 评论关闭

在一个小的工程里面,无论你有什么操作,都因为代码量少,将出错的风险降低。但是在写大工程时,有时候还需要包含几个外部工程。代码的复杂度大大增加,出错的几率也大大增加。会出现一个很简单的失误就导致整个程序的崩溃。而查找起来又是非常的困难。

在实际工作中,我就遇到了这样的事情。在这里说明一下,顺便提醒下自己,以后再编写代码时,一定要注意编程规范。

我所编写的解决方案中,有一个主工程和几个子工程。在测试程序时,发现在关闭程序时,有时候会导致程序挂掉。挂掉的提示是有一处内存被越界访问了。

这个问题如果是在调试状态,就可以根据中断位置,判断大致的出错的位置。但是程序出现这个错误却是在发行版的运行阶段,而且还是非重复,带有随机性质。这就大大的增加错误的排查。我使用写日志的方式,一步步查找,发现是在主工程文档类析构时出现的错误。而主文档类包含的成员变量中,都没有关于内存的处理。所以在析构时,也不会导致出现那种错误。所以整个排查错误过程非常煎熬。花费了大量时间,却一无所获。

最后还是在自己无意查找子工程时,发现了可疑之处。因为主工程中使用了子工程中的类。所以在析构时,也会调用子工程中类的析构。在那个被调用的子工程析构中,有对于内存的处理。是一个正常的for循环。

for (int i=0; i<m_nSheetRow; i++)
	{
		DeleteArrayPointer(m_pStateSheet[i]);
	}
DeleteArrayPointer是我自己定义的宏,是释放堆栈内存的。
问题就出在这个循环中。这个循环的进入条件是i要小于m_nSheetRow,这个m_nSheetRow是个int类型。在VS2008编译环境下,如果是Debug版本,如果定义一个int型变量,而没有赋初值的话,它会默认为非常小的数-858993460。所以即使没有给m_nSheetRow赋初值,也不会进入到循环中。但是在Release版本中,如果没有赋初值,默认值是2021891936,也是随机值。但是会进入循环,但是这时循环里面m_pStateSheet变量并没有值,这样就会导致越界访问,从而导致程序挂掉。
虽说是个简单的错误,但是因为是一个复杂的工程中,导致了出现了严重的后果。而且后期解决错误所花费的精力也是极大。所以一定要注意编码规范。

抱歉!评论已关闭.