为什么在C ++中允许删除空指针

时间:2012-09-22 06:22:45

标签: c++ delete-operator

我记得在某处读过delete NULL有必要成为C ++中的有效操作,但我不记得它应该如此的原因。有人请提醒我吗?

7 个答案:

答案 0 :(得分:14)

确切原因:

  • 因为C ++标准委员会决定这样做。

可能的推理:

  • 因为在用户代码中调用delete之前检查每个指针是否为过多的代码膨胀。

答案 1 :(得分:11)

规则并非严格必要,因为语言可以而不存在;这只是标准委员会做出的决定。空指针不是有效的内存地址。但是,我想相信每个决定都是出于某种原因,这些理由值得了解。

此规则简化了失败案例的管理以及指针可能为null的其他实例。这是一个简单,便宜的检查,它为语言增添了可观的便利。

例如,如果存在许多会导致动态内存分配的条件,但是其他条件也不存在,那么就可以方便地在最后粘贴delete而不用担心它。 / p>

// contrived example
void foo(int n) {
    char *p = nullptr;
    switch(n) {
        case whatever:
        case something_else:
            p = new char[n];
            break;
    }

    // some code...

    delete [] p;  // look Ma, no check!
}

如果delete nullptr是非法的,那么对delete的每次通话都会被......包围。

if(ptr)

......那将是蹩脚的。既然这是常态,一个基本上是强制性的约定,为什么不只是消除完全检查的需要?为什么每次拨打delete都需要额外的5个字符(最少)?

答案 2 :(得分:3)

首先,NULL永远不是有效的指针值(在托管的C ++程序中),因此指针是否指向实时对象没有歧义。其次,内部存储器管理逻辑必须自己进行检查以进行簿记,因此可能无法通过强制指针非空来获得任何结果。

所以现在我们知道没有什么能说明反对这个规则,这里有一个有利的大论点:它使编写代码变得更容易。考虑这个简单的异常处理分配代码:

T * p1 = NULL;
T * p2 = NULL;
T * p3 = NULL;

try
{
    p1 = new T;
    p2 = new T;
    p3 = new T;
}
catch (...)
{
    delete p1;
    delete p2;
    delete p3;

    throw;
}

这很简单,整洁。如果我们需要在任何地方添加NULL检查,那么它将使代码的可读性降低,并使代码的逻辑模糊不清。

答案 3 :(得分:2)

因为标准委员会知道没有程序可以使用NULL来指向有效对象,即NULL不能指向有效内存,所以写delete NULL是安全的,因为它实际上删除任何东西。由于这是安全的,因此在delete

之前,您无需检查NULL
//if (ptr != NULL) NOT NEEDED
   delete ptr; //safe even if ptr == NULL

答案 4 :(得分:2)

因为库实现者只需要编写if (ptr == nullptr) return;一次。您,用户,必须在整个程序中写入9999999999次。因此,这是一个简单的例子,在delete内部进行操作要简单得多。

答案 5 :(得分:1)

删除空指针无效(如果解除分配函数是标准库[2]中提供的那个),因此在调用delete之前不必检查空指针。

还要检查Is it safe to delete a NULL pointer?它可能会对您有所帮助

答案 6 :(得分:0)

好吧,我确实清楚地记得删除指针的规则 - const(现在没问题)随标准化而改变,即它们在ARM中是不同的,注释参考手册。

但我不确定删除0;我认为它一直得到支持。

无论如何,这只是便利性,对于检查成本微不足道的操作,以及编译器可能/可能更有效地完成的操作,而不是某些用户定义的包装函数删除。