我记得在某处读到它是delete NULL
C++ 中的有效操作所必需的,但我不记得为什么它应该如此。有人可以提醒我吗?
7 回答
确切原因:
- 因为 C++ 标准委员会是这样决定的。
可能的推理:
delete
因为在调用用户代码之前检查每个指针是否为 NULL 会导致太多的代码膨胀。
该规则不是严格必要的,因为没有它,语言也可以存在;这只是标准委员会的决定。空指针不是有效的内存地址。但是,我愿意相信每个决定都是有原因的,而这些原因是值得了解的。
此规则简化了对指针可能为空的故障案例和其他实例的管理。这是一种简单、廉价的检查方式,并且为语言增加了明显的便利性。
例如,如果存在许多会导致动态内存分配的条件,但也存在其他不会导致动态内存分配的条件,则可以方便地delete
在末尾粘贴 a 而不用担心它。
// 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)
......那将是蹩脚的。既然这将是规范,一个本质上是强制性的约定,为什么不完全消除检查的需要呢?为什么每次调用都需要额外的 5 个字符(最少)delete
?
首先,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 检查,这会使代码的可读性大大降低,并使代码的逻辑变得模糊。
因为标准委员会知道没有程序可以让 NULL 指向一个有效的对象,即 NULL 不能指向一个有效的内存,所以写是安全的,正是delete NULL
因为它实际上并没有删除任何东西。既然这是安全的,那么它可以让您无需在之前检查 NULL delete
:
//if (ptr != NULL) NOT NEEDED
delete ptr; //safe even if ptr == NULL
因为库实现者只需编写if (ptr == nullptr) return;
一次。作为用户,您必须在整个程序中编写 9999999999 次。因此,这是一个简单的案例,在内部delete
进行操作要简单得多。
删除空指针无效(如果释放函数是标准库[2] 中提供的函数),因此在调用 delete 之前无需检查空指针。
还要检查 删除 NULL 指针是否安全?它可以帮助你
好吧,我确实清楚地记得删除指针的规则const
(现在可以)随着标准化而改变,即它们在 ARM 注释参考手册中有所不同。
但我不确定删除 0;我认为它一直受到支持。
无论如何,这只是为了方便,对于检查成本微不足道的操作,并且编译器可能/可能比某些用户定义的删除包装函数更有效地完成它。