我们仅查找到我们所执行的代码路径中的一个内存写溢出实例,我们凭什么能够断定我们尚未执行到的代码就不会有内存写溢出错误了呢?如果我们检查覆盖率分析,我们就会发现reportSensorFailure()这个函数从未被执行到。我们有必要对这个函数进行测试,但是具体如何进行呢?建立一个调用该函数的单元测试用例就是一个不错的办法。
在单元测试中使用运行时内存监测:我们使用C++test的测试用例向导来创建一个测试用例的框架,并向其中添加一些测试代码。然后运行该测试用例——以检查上面提到的未经测试的函数,同时打开运行时内存监测功能。使用C++teST,全过程大约只需要数秒钟。
结果标明该函数已经被覆盖到了,但同时也查找到了新的错误:
我们的测试用例查找到了更多的内存相关错误。很显然,当失败处理函数被调用时,我们的内存初始化存在问题(空指针)。通过更进一步的分析,我们发现在reportSensorValue()函数中存在函数调用顺序错误。
finalize()函数先于printMessage()函数被调用,但是finalize()函数中释放了printMessage()函数需要使用的内存。
void finalize()
{
if (messages) {
free(messages[0]);
free(messages[1]);
free(messages[2]);
}
free(messages);
}
将函数调用顺序进行修改后,我们重新运行程序。
这样我们就解决了上面报告中的第一个错误。现在我们再来分析报告中的第二个错误:即打印信息中的AccessViolatiONException。产生这个错误的原因是相应的消息列表未经初始化。为了解决该问题,我们在打印该信息前调用一次initialize()函数来对其进行初始化。经修改后的函数如下所示: