指针处理策略无效

时间:2015-03-31 06:11:12

标签: c++ pointers

我认为如果空指针在函数中传递,只需让它gp,我们就可以轻松找到根本原因。但我的队友说我们应该避免生产代码中的gp次数,如果应用程序通常崩溃,客户端可能会感到不安,尽管根本原因可能会被某些空指针保护所覆盖。

当您需要验证指针时,您将使用哪种方法为空?

HRESULT function(const int* pNumber)
{
    { POINTER CHECK for pNumber... }
    ...
}

方法1 - 忽略无效案例

if(pNumber)
{
    int a = *pNumber;   
}   
  • 没有GP
  • 可能进入异常流程
  • 很难找到根本原因

方法2 - 断言指针,在调试模式下发出警告

assert(pNumber);
int a = *pNumber;
  • May GP处于发布模式
  • 永远不要进入异常流程
  • 容易找到根本原因

方法3 - 保留调试消息并返回错误代码

if(!pNumber)
{
    OutputDebugString(L"Error Null pointer in function.\n");
    return E_POINTER;
}
  • 没有GP
  • 切勿在功能内输入异常流量。如果忽略E_POINTER返回
  • ,客户可能会输入异常流出
  • 无声地找不到根本原因

方法4 - 抛出logic_error异常 - 让调用者捕获

if(!pNumber)
{
    throw std::logic_error("Null pointer of pNumber in function");
};
  • 没有GP
  • 当堆栈展开时,没有资源管理(RAII)的代码序列中可能的资源泄漏。
  • 永远不要进入异常流程
  • 很难找到抛出异常的地方

3 个答案:

答案 0 :(得分:2)

如果取消引用nullptr,则输入未定义行为的土地。这意味着,您的编译器没有义务执行anything sensible,因此应该避免这种情况。它也可能决定,因为它是非法的,它从未发生过,因此它会删除相应的代码(从而对其进行优化),并且您遇到逻辑错误而不会遇到一般性保护错误。

如果assert完全无效,我个人更喜欢nullptr - 案例,但在这种情况下,引用可能更为明智。我不认为有一般政策,因为它在很大程度上取决于周围的逻辑。

答案 1 :(得分:1)

例外是一种严重的违约行为,如果您有两个通过接口进行通信的模块,这是有道理的。对于cpp单元本地的静态函数而言,抛出它并不是那么多。考虑在结束时访问数组。它还假设另一方将抓住它。

其他人都不够好。

  • assert(pNumber);就是弱者。可能有一种行为 特定于发布模式,你不会抓住它。而且它是 仅限于您在调试中测试的输入范围(远远不够 从所有)。
  • 忽略无效案例,如上图所示插入你的头部 像鸵鸟一样磨碎。
  • OutputDebugString弱于断言。你最终会让开发者放手 事情随着错误消息滑动,你将会习惯这么多 将停止阅读它们。

所以如果我没有使用例外,我会使用

assert(pNumber);
if(pNumber)
{

}
else
{
   //Log with a logger which has different logging level to the level you seem fit 
}

答案 2 :(得分:0)

我priffer方法2

assert(pNumber);
int a = *pNumber;

因为,在调试模式下,您可以轻松识别断言发生故障的位置。即使在发布模式下,它也确保空值不会继续进入内部功能。用户不会看到任何异常行为,应用程序将正常工作。