8

我们使用Parasoft C++test来静态分析我们的代码。它在使用如下代码时遇到问题:

void foo(int* x) {
    try {
        bar();
    } catch(...) {
        delete x;
        throw;
    }

    *x;
}

它在线警告*x;说:

在任何情况下都不应随后访问已释放的内存

不知何故,可以得出结论,控制流可以传递到catch(...)块中,删除x,越过throw;,然后到达*x;. 我尝试throw std::exception("");了其他几个,得到了同样的结果。Parasoft 当然知道异常并将它们合并到其控制流中,因为还有许多其他测试涉及异常检查。在这种情况下只是混淆了,还是实际上有某种方法可以让这个程序的执行同时击中delete x;and *x;

4

3 回答 3

2

所以这个工具是错误的(我知道之前已经说过),我假设你不想改变警告。

我同意@Pascal 的评论,即仅仅为了解决某些工具的限制而重写代码有点危险。您可以做的是仅针对您当前遇到此问题的文件禁用此警告。

然后,您有一个无警告构建开始,没有工具告诉您重写现有的有效代码。

对于新代码,您必须采用该工具可以理解的某种样式。这不是一个问题,因为这将是您当前正在处理的代码,因此如果您需要稍微重写它以消除警告,这将不是一个问题。

虽然正确,但现有的风格远非理想。

我建议将指针存储x在 auto_ptr 中。如果 auto_ptr 超出范围,它将自动删除它的内容 - 除非您明确将其从 auto_ptr 中取出。这在视觉上要容易得多,并且也很好地证明了该函数拥有指针的所有权。

void foo(auto_ptr<int> x)
{
    bar();
    *x;
}

我希望 ParaSoft 对这段代码没有任何问题。

于 2011-05-02T18:10:15.850 回答
0

也许这是一个愚蠢的建议,但如果你把问题留到最后,Parasoft 会说什么?IE

void foo(int* x) 
  {
  try 
    {
    bar();
    *x;
    } 
  catch(...) 
    {
    delete x;
    throw;
    }      
  }

我意识到这可能不适用于语句和异常的所有组合,例如,如果您有多种异常类型要在 foo 的不同阶段以不同的处理方式捕获,但如果您真的想要,至少它可能会给您一个解决方法的开始摆脱警告。

于 2011-04-27T14:46:25.817 回答
0

快速更新:

1)上述规则根本不是流量分析规则。话虽如此,该规则(ID MRM-31)在 C++test 9.2.0 及更高版本中得到了改进。在 C++test (ID: BD-RES-FREE) 中也有一个相应的流分析规则,应该做你想做的。

于 2013-06-03T22:43:43.857 回答