#define SAFE_DELETE(a) if((a) != NULL) delete (a); (a) = NULL;
template<typename T> void safe_delete(T*& a) {
delete a;
a = NULL;
}
或任何其他更好的办法
#define SAFE_DELETE(a) if((a) != NULL) delete (a); (a) = NULL;
template<typename T> void safe_delete(T*& a) {
delete a;
a = NULL;
}
或任何其他更好的办法
很明显的功能,原因很简单。宏多次评估其论证。这可能有不良副作用。此外,该功能可以作用域。没有什么比这更好的:)
一般来说,喜欢内联函数在宏,因为宏不尊重的范围,并可以与预处理过程中的一些符号发生冲突,导致很奇怪的编译错误。
当然,有时模板和函数不会这样做,但在这里并不是这样。
此外,更好的安全删除是不必要的,因为您可以使用智能指针,因此不需要记住在客户端代码中使用此方法,而是封装它。
(编辑)正如其他人所指出的,安全的,删除是不是安全,因为即使有人不不忘记使用它,它仍然可能没有预期的效果。所以它实际上完全没有价值,因为正确使用safe_delete需要的不仅仅是自己设置为0。
删除a;
ISO C++指定,在NULL指针上删除就不会执行任何操作。从ISO 14882
引用:
5.3.5 Delete [expr.delete] 2 [...] In either alternative, if the value of the operand of delete is the null pointer the operation has no effect. [...]
问候,博多
/编辑:我没有注意到一个= NULL;在原来的帖子中,如此新的版本:删除一个;一个= NULL;然而,设置a = NULL的问题已经被指出(错误的安全感)。
关于测试NULL和性能:我知道delete可以用NULL来调用,但是if(p!= NULL)是一个快速读取操作,可以跳过函数调用和一个assignement(写入记忆)。删除if没有错,但初级程序员读取它和性能如何? – 2016-02-10 15:51:25
真的,另一方面:测试NULL是一个条件跳转。如果以某种方式编写代码,通常不会释放NULL指针,那么您只需复制该条件跳转,因为您自己执行该操作,然后调用函数,然后再次执行。所以在我的选择中,最好教导做适当的资源跟踪而不是做NULL测试。 – 2016-03-21 16:06:03
您无需使用delete
进行无效测试,它相当于无操作。 (a) = NULL
让我抬起眉毛。第二种选择更好。
但是,如果您有选择,您应该使用智能指针,如std::auto_ptr
或tr1::shared_ptr
,这些指针已经为您执行此操作。
删除时,auto_ptr和shared_ptr都不会设置为NULL。 QPointer是我知道的唯一一个这样做的课程。 – 2009-03-20 16:35:07
我不会说,因为两者都会给你一种虚假的安全感。例如,假设您有一个函数:
void Func(SomePtr * p) {
// stuff
SafeDelete(p);
}
您将p设置为NULL,但函数外部的副本不受影响。
但是,如果您必须执行此操作,请使用模板 - 宏将始终有可能对其他名称进行拼凑。
好吧,一个疯狂的家伙正在潜伏着。上一个。这个答案是正确的... – gimpf 2009-02-12 11:44:23
+1删除它后将指针设置为NULL很少有意义。 – 2009-02-12 14:32:33
我觉得
#define SAFE_DELETE(pPtr) { delete pPtr; pPtr = NULL }
更好
正如前面提到的那样,第二个是更好的一个,而不是一个有潜在副作用的宏,没有对NULL的不需要的检查(尽管我怀疑你是这样做的一种类型检查)等,但都不是很有希望的安全。如果您确实使用了类似tr1 :: smart_ptr的内容,请确保您阅读了他们的文档,并确保它具有适合您的任务的正确语义。我最近不得不寻找并清理了一个巨大的内存泄漏,这是由于同事将smart_ptrs放入具有循环链接的数据结构:)(他应该使用weak_ptrs作为后向引用)
SAFE_DELETE的使用确实出现成为C程序员的方法来控制C++中内置的内存管理。我的问题是:C++是否允许这种方法使用SAFE_DELETE指针已被适当封装为私人?这个宏只能用于声明为Public的指针吗? OOP坏了!
我喜欢这个版本:
3210删除它是毫无意义的,因为你会使用指针的唯一原因是,以允许在多个地方同时引用的对象后设置指针为null 。即使程序的一部分中的指针为0,也可能有其他的未设置为0.
此外,safe_delete宏/函数模板非常难以正确使用,因为它只有两个地方可以使用,如果有代码可能会抛出新的和删除给定的指针。
1)无论是里面的catch(...)块重新抛出异常,毗邻为不丢的路径赶上(...)块也被复制。 (也可以在每个中断旁边复制,返回,继续等等,这可能会使指针超出范围)
2)在拥有指针的对象的析构函数内部(除非新的和删除之间没有代码可以抛出)。
即使没有代码会抛出异常,当你写的代码,这可能在未来改变(所需要的是有人走过来,再添新后的第一个)。即使在例外情况下,仍然保持正确的编写代码更好。
选项1创建了很多代码重复,很容易出错,我甚至怀疑它可以称之为选项。
选项2会使safe_delete变得冗余,因为您设置为0的ptr_将超出下一行的范围。
概括 - 因为它是不是在所有安全不使用SAFE_DELETE(这是非常困难的正确使用,并导致冗余代码,即使它的使用是正确的)。使用SBRM和智能指针。
其仍然愚蠢,但宏安全删除应该是:#define SAFE_DELETE(a)do {delete(a); (a)= NULL; } while(0) – 2009-02-12 14:28:50